feat(game): 添加 FC 游戏相关功能

- 新增 FC游戏平台支持
- 添加 FC 游戏列表、登录、余额转移等接口
- 实现 FC 投注记录获取功能
- 增加 FC 游戏类型和传输类型枚举
- 优化游戏注单 ID 处理,改为字符串类型
main-cf
shi 2025-03-25 17:04:25 +08:00
parent c9797d57c5
commit c7b001d667
32 changed files with 926 additions and 438 deletions

View File

@ -57,6 +57,13 @@ public class CacheConstants
*/ */
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:";
/** /**
* pg * pg
*/ */

View File

@ -23,7 +23,11 @@ public enum ErrorCode {
FREQUENT_INTERFACE_REQUESTS (1007, "接口请求频繁"), FREQUENT_INTERFACE_REQUESTS (1007, "接口请求频繁"),
BALANCE_TRANSFER_FAILED (1008, "余额转移失败"), BALANCE_TRANSFER_FAILED (1008, "余额转移失败"),
LANG_NOT_EXIST(1009, "游戏平台不支持的语言"), LANG_NOT_EXIST(1009, "游戏平台不支持的语言"),
ORDER_NOT_EXIST(1010, "订单不存在") ORDER_NOT_EXIST(1010, "订单不存在"),
PLAYERS_ARE_PLAYING(1011, "玩家游玩中"),
INSUFFICIENT_PLAYER_BALANCE(1012, "玩家余额不足"),
KICK_OUT_AILED(1013, "玩家踢出失败"),
ACCOUNT_NOT_ONLINE(1014, "账号不在线"),
; ;
// 获取错误码 // 获取错误码

View File

@ -0,0 +1,68 @@
package com.ff.base.enums;
import lombok.Getter;
import java.util.HashMap;
import java.util.Optional;
import java.util.stream.Stream;
/**
* xkgame
*
* @author shi
* @date 2024/11/13
*/
@Getter
public enum FCGameType {
CATCH_FISH("fishing", 4,"捕鱼"),
ARCADE("arcade",1, "电子"),
SLOT("slot",1, "电子"),
TABLE("table", 1,"电子"),
CATCH_FISH_MEMBER("1", 4,"捕鱼"),
ARCADE_MEMBER("2", 1,"电子"),
SLOT_MEMBER("7", 1,"电子"),
TABLE_MEMBER("8", 1,"电子"),
;
private final String code;
private final Integer systemCode;
private final String info;
FCGameType(String code, Integer systemCode, String info)
{
this.code = code;
this.systemCode = systemCode;
this.info = info;
}
/**
*
*
* @param code
* @return {@link String }
*/
public static Integer findSystemByCode(String code) {
Optional<Integer> system = Stream.of(FCGameType.values())
.filter(gameType -> gameType.getCode().equals(code))
.map(FCGameType::getSystemCode)
.findFirst();
return system.orElse(null);
}
/**
*
*
* @param code
* @return {@link String }
*/
public static String findInfoByCode(String code) {
Optional<String> system = Stream.of(FCGameType.values())
.filter(gameType -> gameType.getCode().equals(code))
.map(FCGameType::getInfo)
.findFirst();
return system.orElse(null);
}
}

View File

@ -0,0 +1,23 @@
package com.ff.base.enums;
import lombok.Getter;
/**
*
*
* @author shi
* @date 2025/03/12
*/
@Getter
public enum FCTransferType {
TRANSFER_OUT("0", "不全部提领(默认值)"),
TRANSFER_OUT_ALL("1", "全部提领(包含所有小数字金额)");
private final String value;
private final String description;
FCTransferType(String value, String description) {
this.value = value;
this.description = description;
}
}

View File

@ -7,6 +7,7 @@ public enum GamePlatforms {
JILI("JILI", "JILI"), JILI("JILI", "JILI"),
XK("XK", "XK"), XK("XK", "XK"),
PG("PG", "PG"), PG("PG", "PG"),
FC("FC", "FC"),
; ;
private final String code; private final String code;

View File

@ -0,0 +1,30 @@
package com.ff.base.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author shi
* @date 2025/03/25
*/
@Getter
@AllArgsConstructor
public enum PlatformType {
ELECTRONIC(1, "电子"),
CARD_GAME(2, "棋牌"),
GAME_HALL(3, "游戏大厅"),
FISHING(4, "捕鱼"),
BETTING_MACHINE(5, "押分机 (含宾果)"),
VIDEO(6, "视讯"),
LOTTERY(7, "彩票"),
SPORTS(8, "体育"),
HUNTING(9, "捕猎");
private final int code;
private final String name;
}

View File

@ -9,8 +9,7 @@ package com.ff.base.enums;
*/ */
public enum TransferType { public enum TransferType {
ALL(1, "从游戏商转移额度到平台商(不看amount值全部转出"), ALL(1, "从游戏商转移额度到平台商(不看amount值全部转出"),
GAMES(2, "从平台商转移额度到游戏商"), GAMES(2, "从平台商转移额度到游戏商");
SYSTEM(3, "从游戏商转移额度到平台商 无用");
private final Integer code; private final Integer code;
private final String info; private final String info;

View File

@ -202,6 +202,27 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
return zdt.format(formatter); return zdt.format(formatter);
} }
/**
*
*
* @param timestampInMillis
* @param timeZone America/New_York
* @param format yyyy-MM-dd HH:mm:ss
* @return
*/
public static String convertTimeZone(long timestampInMillis, String timeZone, String format) {
// 将毫秒时间戳转换为 Instant
Instant instant = Instant.ofEpochMilli(timestampInMillis);
// 将 UTC 时间转换为指定时区的时间
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of(timeZone));
// 格式化输出为指定格式的时间字符串
return zonedDateTime.format(DateTimeFormatter.ofPattern(format));
}
/** /**
* LocalDate ==> Date * LocalDate ==> Date
*/ */

View File

@ -261,7 +261,6 @@ public class ApiGameController extends BaseController {
} }
/** /**
* *
* *
@ -352,7 +351,6 @@ public class ApiGameController extends BaseController {
public AjaxResult getDetail(@Validated @RequestBody GameGetDetailRequest gameGetDetailRequest) { public AjaxResult getDetail(@Validated @RequestBody GameGetDetailRequest gameGetDetailRequest) {
GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder() GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
.platformCode(gameGetDetailRequest.getPlatformCode()) .platformCode(gameGetDetailRequest.getPlatformCode())
.systemCurrency(gameGetDetailRequest.getCurrencyCode()).build()); .systemCurrency(gameGetDetailRequest.getCurrencyCode()).build());
@ -365,7 +363,6 @@ public class ApiGameController extends BaseController {
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
GameSecretKeyLangDTO gameSecretKeyLang = gameSecretKeyLangService.findGameSecretKeyLangDTO(GameSecretKeyLangDTO.builder() GameSecretKeyLangDTO gameSecretKeyLang = gameSecretKeyLangService.findGameSecretKeyLangDTO(GameSecretKeyLangDTO.builder()
.platformCode(gameGetDetailRequest.getPlatformCode()) .platformCode(gameGetDetailRequest.getPlatformCode())
.systemLangCode(gameGetDetailRequest.getLangCode()) .systemLangCode(gameGetDetailRequest.getLangCode())
@ -373,7 +370,6 @@ public class ApiGameController extends BaseController {
ApiException.notNull(gameSecretKeyLang, ErrorCode.LANG_NOT_EXIST.getCode()); ApiException.notNull(gameSecretKeyLang, ErrorCode.LANG_NOT_EXIST.getCode());
GetGameDetailResponseDTO gameDetail = iGamesService.getGameDetail(GetGameDetailRequestDTO.builder() GetGameDetailResponseDTO gameDetail = iGamesService.getGameDetail(GetGameDetailRequestDTO.builder()
.wagersId(gameGetDetailRequest.getWagersId()) .wagersId(gameGetDetailRequest.getWagersId())
.lang(gameSecretKeyLang.getLang()) .lang(gameSecretKeyLang.getLang())
@ -397,7 +393,6 @@ public class ApiGameController extends BaseController {
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode()); ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
Member member = memberService.selectMemberByAccount(gameKickMemeberRequest.getAccount(), gameKickMemeberRequest.getCurrencyCode(), gameKickMemeberRequest.getPlatformCode()); Member member = memberService.selectMemberByAccount(gameKickMemeberRequest.getAccount(), gameKickMemeberRequest.getCurrencyCode(), gameKickMemeberRequest.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode()); ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
@ -409,6 +404,7 @@ public class ApiGameController extends BaseController {
return AjaxResult.success(iGamesService.kickMember(KickMemberRequestDTO.builder() return AjaxResult.success(iGamesService.kickMember(KickMemberRequestDTO.builder()
.account(member.getGameAccount()) .account(member.getGameAccount())
.agentId(gameSecretKey.getCode()) .agentId(gameSecretKey.getCode())
.currency(gameSecretKey.getCurrency())
.agentKey(gameSecretKey.getKey()) .agentKey(gameSecretKey.getKey())
.build())); .build()));
} }
@ -424,9 +420,12 @@ public class ApiGameController extends BaseController {
IGamesService iGamesService = gamesService.get(gameKickMemeberAllRequest.getPlatformCode() + Constants.SERVICE); IGamesService iGamesService = gamesService.get(gameKickMemeberAllRequest.getPlatformCode() + Constants.SERVICE);
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
KickMemberAllDTO kickMemberAllDTO = KickMemberAllDTO.builder() KickMemberAllDTO kickMemberAllDTO = KickMemberAllDTO.builder()
.agentId(gameSecretKey.getCode()) .agentId(gameSecretKey.getCode())
.agentKey(gameSecretKey.getKey()) .agentKey(gameSecretKey.getKey())
.currency(gameSecretKey.getCurrency())
.build(); .build();
if (!ObjectUtils.isEmpty(gameKickMemeberAllRequest.getGameId())) { if (!ObjectUtils.isEmpty(gameKickMemeberAllRequest.getGameId())) {
Game game = gameService.selectGameById(gameKickMemeberAllRequest.getGameId()); Game game = gameService.selectGameById(gameKickMemeberAllRequest.getGameId());
@ -508,9 +507,6 @@ public class ApiGameController extends BaseController {
TenantSecretKey tenantSecretKey = keyConfig.get(); TenantSecretKey tenantSecretKey = keyConfig.get();
List<GameSecretKeyCurrencyDTO> gameSecretKeys = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTOList(GameSecretKeyCurrencyDTO.builder() List<GameSecretKeyCurrencyDTO> gameSecretKeys = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTOList(GameSecretKeyCurrencyDTO.builder()
.systemCurrency(gameExchangeBalanceAllRequest.getCurrencyCode()).build()); .systemCurrency(gameExchangeBalanceAllRequest.getCurrencyCode()).build());

View File

@ -39,8 +39,8 @@ public class GameGetDetailRequest implements Serializable {
/** /**
* id * id
*/ */
@NotNull(message = "wagersId不能为空") @NotBlank(message = "wagersId不能为空")
private Long wagersId; private String wagersId;
/** /**
* *

View File

@ -80,6 +80,14 @@ public interface IGamesService {
Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO); Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO);
/**
*
*
* @param betRecordByTimeDTO dto
* @return {@link Boolean }
*/
Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO);
/** /**
* *
* *

View File

@ -19,6 +19,6 @@ public class MyFCAddressSource implements AddressSource {
@Override @Override
public ForestAddress getAddress(ForestRequest request) { public ForestAddress getAddress(ForestRequest request) {
String apiBaseUrl = configService.selectConfigByKey(Constants.FC_API_BASE_URL); String apiBaseUrl = configService.selectConfigByKey(Constants.FC_API_BASE_URL);
return new ForestAddress("http",apiBaseUrl, 80,""); return new ForestAddress("https",apiBaseUrl, 443,"");
} }
} }

View File

@ -2,15 +2,12 @@ package com.ff.game.api.fc.client;
import com.dtflys.forest.annotation.Address; import com.dtflys.forest.annotation.Address;
import com.dtflys.forest.annotation.Header;
import com.dtflys.forest.annotation.JSONBody; import com.dtflys.forest.annotation.JSONBody;
import com.dtflys.forest.annotation.Post; import com.dtflys.forest.annotation.Post;
import com.ff.game.api.fc.dto.ApiFCResult; import com.ff.game.api.fc.dto.*;
import com.ff.game.api.fc.address.MyFCAddressSource; import com.ff.game.api.fc.address.MyFCAddressSource;
import com.ff.game.api.fc.dto.ApiKeyRequest;
import com.ff.game.api.ng.dto.*; import com.ff.game.api.ng.dto.*;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -22,8 +19,7 @@ import java.util.Map;
@Address(source = MyFCAddressSource.class) @Address(source = MyFCAddressSource.class)
public interface FCClient { public interface FCClient {
@Post("/Key")
ApiKeyRequest key(@JSONBody Map<String, Object> parameters);
/** /**
@ -35,80 +31,83 @@ public interface FCClient {
@Post("/AddMember") @Post("/AddMember")
ApiFCResult createMember(@JSONBody Map<String, Object> parameters); ApiFCResult createMember(@JSONBody Map<String, Object> parameters);
/**
*
*
* @param parameters
* @return {@link ApiFCResult }
*/
@Post("/KickOut")
ApiFCResult kickMember(@JSONBody Map<String, Object> parameters);
/**
*
*
* @param parameters
* @return {@link ApiFCResult }
*/
@Post("/KickoutAll")
ApiFCResult kickMemberAll(@JSONBody Map<String, Object> parameters);
/** /**
* *
* *
* @param parameters * @param parameters
* @param headerMap
* @return {@link ApiNGResponseDTO }<{@link String }> * @return {@link ApiNGResponseDTO }<{@link String }>
*/ */
@Post("/server/balance") @Post("/SearchMember")
ApiNGResponseDTO<ApiMemberInfoResponseDTO> getMemberInfo(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap); ApiFCUserInfoResponseDTO getMemberInfo(@JSONBody Map<String, Object> parameters);
/** /**
* *
* *
* @param parameters * @param parameters
* @param headerMap * @return {@link ApiFCGameListResponseDTO }
* @return {@link ApiNGResponseDTO }<{@link List<ApiGameInfoResponseDTO> }>
*/ */
@Post("/server/gameCode") @Post("/GetGameIconList")
ApiNGResponseDTO<List<ApiGameInfoResponseDTO>> getGameList(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap); ApiFCGameListResponseDTO getGameList(@JSONBody Map<String, Object> parameters);
/** /**
* *
* *
* @param parameters * @param parameters
* @param headerMap * @return {@link ApiFCLoginResponseDTO }
* @return {@link ApiNGResponseDTO }<{@link ApiLoginResponseDTO }>
*/ */
@Post("/server/gameUrl") @Post("/Login")
ApiNGResponseDTO<ApiLoginResponseDTO> loginWithoutRedirect(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap); ApiFCLoginResponseDTO loginWithoutRedirect(@JSONBody Map<String, Object> parameters);
/** /**
* id * id
* *
* @param parameters * @param parameters
* @param headerMap
* @return {@link ApiNGResponseDTO }<{@link ApiLoginResponseDTO }>
*/ */
@Post(url = "/server/transfer",connectTimeout = 70000) @Post(url = "/SetPoints",connectTimeout = 70000)
ApiNGResponseDTO exchangeTransferByAgentId(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap); ApiCFBalanceTransferResponseDTO exchangeTransferByAgentId(@JSONBody Map<String, Object> parameters);
/**
*
*
* @param parameters
* @param headerMap
* @return {@link ApiNGResponseDTO }<{@link ApiExchangeTransferStatusResponseDTO }>
*/
@Post(url = "/server/transferStatus")
ApiNGResponseDTO<ApiExchangeTransferStatusResponseDTO> exchangeTransferStatus(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap);
/** /**
* *
* *
* @param parameters * @param parameters
* @param headerMap
* @return {@link ApiNGResponseDTO }<{@link ApiGameBetRecordPageResponseDTO }>
*/ */
@Post(url = "server/recordAll") @Post(url = "/GetRecordList")
ApiNGResponseDTO<ApiGameBetRecordPageResponseDTO> getBetRecordByTime(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap); ApiFCBetRecordResponseDTO getBetRecordByTime(@JSONBody Map<String, Object> parameters);
/** /**
* *
* *
* @param parameters * @param parameters
* @param headerMap * @return {@link ApiFCBetRecordResponseDTO }
* @return {@link ApiNGResponseDTO }<{@link ApiGameBetRecordPageResponseDTO }>
*/ */
@Post(url = "server/recordHistory") @Post(url = "/GetHistoryRecordList")
ApiNGResponseDTO<ApiGameBetRecordPageResponseDTO> getBetRecordByHistoryTime(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap); ApiFCBetRecordResponseDTO getBetRecordByHistoryTime(@JSONBody Map<String, Object> parameters);
} }

View File

@ -0,0 +1,47 @@
package com.ff.game.api.fc.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* apidto
*
* @author shi
* @date 2025/03/25
*/
@Data
public class ApiCFBalanceTransferResponseDTO {
/**
* 0
*/
@JsonProperty("Result")
private int result;
/**
* ID
*/
@JsonProperty("BankID")
private int bankID;
/**
* ID
*/
@JsonProperty("TrsID")
private String trsID;
/**
*
*/
@JsonProperty("AfterPoint")
private BigDecimal afterPoint;
/**
*
*/
@JsonProperty("Points")
private BigDecimal points;
}

View File

@ -0,0 +1,166 @@
package com.ff.game.api.fc.dto;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
*
*/
@Data
public class ApiFCBetRecordResponseDTO {
/**
* 0
*/
@JsonProperty("Result")
private int Result;
/**
*
*/
@JsonProperty("Records")
private List<BetRecord> Records;
/**
*
*/
@Data
public static class BetRecord {
/**
*
*/
@JsonProperty("bet")
private BigDecimal bet;
/**
* ( Lucky9 Bet = validBet)
*/
@JsonProperty("validBet")
private BigDecimal validBet;
/**
*
*/
@JsonProperty("prize")
private BigDecimal prize;
/**
* 退 ( Lucky9 refund = win)
*/
@JsonProperty("refund")
private BigDecimal refund;
/**
* prize - validBet
*/
@JsonProperty("winlose")
private BigDecimal winlose;
/**
* ( Lucky9 0)
*/
@JsonProperty("commission")
private BigDecimal commission;
/**
*
*/
@JsonProperty("before")
private BigDecimal before;
/**
*
*/
@JsonProperty("after")
private BigDecimal after;
/**
* ()
*/
@JsonProperty("jptax")
private BigDecimal jptax;
/**
*
*/
@JsonProperty("jppoints")
private BigDecimal jppoints;
/**
*
*/
@JsonProperty("inGameJptax")
private BigDecimal inGameJptax;
/**
*
*/
@JsonProperty("inGameJppoints")
private BigDecimal inGameJppoints;
/**
* ()24
*/
@JsonProperty("recordID")
private String recordID;
/**
*
*/
@JsonProperty("account")
private String account;
/**
*
*/
@JsonProperty("gameID")
private String gameID;
/**
*
*/
@JsonProperty("gametype")
private String gametype;
/**
*
*/
@JsonProperty("jpmode")
private int jpmode;
/**
*
*/
@JsonProperty("inGameJpmode")
private int inGameJpmode;
/**
*
*/
@JsonProperty("bdate")
private Date bdate;
/**
*
*/
@JsonProperty("isBuyFeature")
private boolean isBuyFeature;
/**
*
*/
@JsonProperty("gameMode")
private int gameMode;
}
}

View File

@ -0,0 +1,67 @@
package com.ff.game.api.fc.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.Map;
/**
* API DTO
*/
@Data
public class ApiFCGameListResponseDTO {
/**
* 0
*/
@JsonProperty("Result")
private int result;
/**
*
*/
@JsonProperty("GetGameIconList")
private Map<String, Map<String, GameDetails>> getGameIconList;
/**
*
*/
@Data
public static class GameDetails {
/**
*
*/
private String status;
/**
* id
*/
private Long systemGameId;
/**
* id
*/
private String gameId;
/**
*
*/
private String gameNameOfChinese;
/**
*
*/
private String gameNameOfEnglish;
/**
* URL
*/
private String enUrl;
/**
* URL
*/
private String cnUrl;
}
}

View File

@ -0,0 +1,24 @@
package com.ff.game.api.fc.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* API DTO
*/
@Data
public class ApiFCLoginResponseDTO {
/**
* 0
*/
@JsonProperty("Result")
private int result;
/**
* URL
*/
@JsonProperty("Url")
private String url;
}

View File

@ -0,0 +1,35 @@
package com.ff.game.api.fc.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* API DTO
*
* @author shi
* @date 2025/03/25
*/
@Data
public class ApiFCUserInfoResponseDTO {
/**
* 0
*/
@JsonProperty("Result")
private int result;
/**
* 线
*/
@JsonProperty("OnlineType")
private int onlineType;
/**
*
*/
@JsonProperty("Points")
private BigDecimal points;
}

View File

@ -11,20 +11,16 @@ import com.ff.base.exception.base.ApiException;
import com.ff.base.exception.base.BaseException; import com.ff.base.exception.base.BaseException;
import com.ff.base.system.service.ISysConfigService; import com.ff.base.system.service.ISysConfigService;
import com.ff.base.utils.DateUtils; import com.ff.base.utils.DateUtils;
import com.ff.base.utils.SleepUtil;
import com.ff.base.utils.StringUtils;
import com.ff.base.utils.sign.Md5Utils; import com.ff.base.utils.sign.Md5Utils;
import com.ff.config.KeyConfig; import com.ff.config.KeyConfig;
import com.ff.game.api.IGamesService; import com.ff.game.api.IGamesService;
import com.ff.game.api.fc.dto.ApiFCResult; import com.ff.game.api.fc.dto.*;
import com.ff.game.api.fc.client.FCClient; import com.ff.game.api.fc.client.FCClient;
import com.ff.game.api.ng.dto.*; import com.ff.game.api.ng.client.NGClient;
import com.ff.game.api.request.*; import com.ff.game.api.request.*;
import com.ff.game.domain.*; import com.ff.game.domain.*;
import com.ff.game.dto.GameBettingDetailsDTO; import com.ff.game.dto.GameBettingDetailsDTO;
import com.ff.game.dto.GameDTO;
import com.ff.game.dto.GameSecretKeyCurrencyDTO; import com.ff.game.dto.GameSecretKeyCurrencyDTO;
import com.ff.game.dto.GameSecretKeyLangDTO;
import com.ff.game.service.*; import com.ff.game.service.*;
import com.ff.member.domain.Member; import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService; import com.ff.member.service.IMemberService;
@ -43,12 +39,8 @@ import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -122,9 +114,10 @@ public class GamesFCServiceImpl implements IGamesService {
* @return {@link Boolean } * @return {@link Boolean }
*/ */
private Boolean getIsSuccess(Integer errorCode) { private Boolean getIsSuccess(Integer errorCode) {
ApiException.isTrue(10009 != errorCode, ErrorCode.FREQUENT_INTERFACE_REQUESTS.getCode()); ApiException.isTrue(503 != errorCode, ErrorCode.PLAYERS_ARE_PLAYING.getCode());
ApiException.isTrue(203 != errorCode, ErrorCode.INSUFFICIENT_PLAYER_BALANCE.getCode());
return 10000 == errorCode; ApiException.isTrue(504 != errorCode, ErrorCode.ACCOUNT_NOT_ONLINE.getCode());
return 0 == errorCode;
} }
@ -149,7 +142,6 @@ public class GamesFCServiceImpl implements IGamesService {
} }
/** /**
* *
* *
@ -158,13 +150,13 @@ public class GamesFCServiceImpl implements IGamesService {
* @param currency * @param currency
* @return {@link Map }<{@link String },{@link Object }> * @return {@link Map }<{@link String },{@link Object }>
*/ */
private Map<String,Object> getKeyMap(Map<String,Object> paramsMap,String agentKey,String currency){ private Map<String, Object> getKeyMap(Map<String, Object> paramsMap, String agentKey, String currency, String agentId) {
Map<String, Object> keyMap = new HashMap<>(); Map<String, Object> keyMap = new HashMap<>();
String key = getKey(paramsMap, agentKey); String key = getKey(paramsMap, agentKey);
keyMap.put("Sign", Md5Utils.md5New(JSONUtils.toJSONString(paramsMap))); keyMap.put("Sign", Md5Utils.md5New(JSONUtils.toJSONString(paramsMap)));
keyMap.put("AgentCode", "TTCS"); keyMap.put("AgentCode", agentId);
keyMap.put("Currency", currency); keyMap.put("Currency", currency);
keyMap.put("Params",key); keyMap.put("Params", key);
return keyMap; return keyMap;
} }
@ -177,7 +169,7 @@ public class GamesFCServiceImpl implements IGamesService {
*/ */
private String decryptKey(GamesBaseRequestDTO gamesBaseRequestDTO) { private String decryptKey(GamesBaseRequestDTO gamesBaseRequestDTO) {
try { try {
String val="SBF6G5gFvW5n4aFSFCar9Im0CHgBMyU7OxFTuuB6InmRkm6Qt4K2pfktU="; String val = "SBF6G5gFvW5n4aFSFCar9Im0CHgBMyU7OxFTuuB6InmRkm6Qt4K2pfktU=";
Base64.Decoder decoder = Base64.getDecoder(); Base64.Decoder decoder = Base64.getDecoder();
SecretKeySpec keySpec = new SecretKeySpec("gamesBaseRequestDTO.getAgentKey()".getBytes(), "AES"); SecretKeySpec keySpec = new SecretKeySpec("gamesBaseRequestDTO.getAgentKey()".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
@ -185,6 +177,7 @@ public class GamesFCServiceImpl implements IGamesService {
return new String(cipher.doFinal(decoder.decode(val))); return new String(cipher.doFinal(decoder.decode(val)));
} catch (Exception e) { } catch (Exception e) {
throw new BaseException("解密失败"); throw new BaseException("解密失败");
} }
} }
@ -197,18 +190,15 @@ public class GamesFCServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) { public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) {
log.info("GamesNGServiceImpl [createMember] 请求参数 {}", createMemberRequestDTO); log.info("GamesFCServiceImpl [createMember] 请求参数 {}", createMemberRequestDTO);
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("MemberAccount", createMemberRequestDTO.getAccount()); paramsMap.put("MemberAccount", createMemberRequestDTO.getAccount());
paramsMap.putAll(getKeyMap(paramsMap, createMemberRequestDTO.getAgentKey(), createMemberRequestDTO.getCurrency())); paramsMap.putAll(getKeyMap(paramsMap, createMemberRequestDTO.getAgentKey(), createMemberRequestDTO.getCurrency(), createMemberRequestDTO.getAgentId()));
ApiFCResult apiFCResult = FCClient.createMember(paramsMap); ApiFCResult apiFCResult = FCClient.createMember(paramsMap);
int errorCode = apiFCResult.getResult(); int errorCode = apiFCResult.getResult();
if (10000 == errorCode) { if (0 == errorCode) {
return Boolean.TRUE; return Boolean.TRUE;
} }
if (10002 == errorCode) {
throw new ApiException(ErrorCode.GAME_ACCOUNT_CREATION_FAILED.getCode());
}
//判断是否获取成功 //判断是否获取成功
return Boolean.FALSE; return Boolean.FALSE;
} }
@ -222,19 +212,18 @@ public class GamesFCServiceImpl implements IGamesService {
*/ */
@Override @Override
public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) { public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) {
log.info("GamesNGServiceImpl [getMemberInfo] 请求参数 {}", memberInfoRequestDTO); log.info("GamesFCServiceImpl [getMemberInfo] 请求参数 {}", memberInfoRequestDTO);
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("playerId", memberInfoRequestDTO.getAccounts()); paramsMap.put("MemberAccount", memberInfoRequestDTO.getAccounts());
paramsMap.put("platType", NGPlatforms.PG.getCode()); paramsMap.putAll(getKeyMap(paramsMap, memberInfoRequestDTO.getAgentKey(), memberInfoRequestDTO.getCurrency(), memberInfoRequestDTO.getAgentId()));
paramsMap.put("currency", memberInfoRequestDTO.getCurrency()); ApiFCUserInfoResponseDTO apiFCUserInfoResponseDTO = FCClient.getMemberInfo(paramsMap);
//这个接口请求稍微重复一次就报错 int errorCode = apiFCUserInfoResponseDTO.getResult();
SleepUtil.sleep(500);
ApiNGResponseDTO<ApiMemberInfoResponseDTO> apiNGResponseDTO = FCClient.getMemberInfo(paramsMap, null);
int errorCode = apiNGResponseDTO.getCode();
if (this.getIsSuccess(errorCode)) { if (this.getIsSuccess(errorCode)) {
return MemberInfoResponseDTO.builder().account(memberInfoRequestDTO.getAccounts()).balance(apiNGResponseDTO.getData().getBalance()).status(GameMemberStatus.UNKNOWN.getCode()).build(); return MemberInfoResponseDTO.builder().account(memberInfoRequestDTO.getAccounts())
.balance(apiFCUserInfoResponseDTO.getPoints())
.status(apiFCUserInfoResponseDTO.getOnlineType() != 0 ? GameMemberStatus.ONLINE.getCode() : GameMemberStatus.OFFLINE.getCode()).build();
} else { } else {
throw new BaseException(apiNGResponseDTO.getMsg()); throw new ApiException(ErrorCode.ACCOUNT_NOT_EXIST.getCode());
} }
} }
@ -246,22 +235,18 @@ public class GamesFCServiceImpl implements IGamesService {
*/ */
@Override @Override
public String loginWithoutRedirect(GamesLogin gamesLogin) { public String loginWithoutRedirect(GamesLogin gamesLogin) {
log.info("GamesNGServiceImpl [loginWithoutRedirect] 请求参数 {}", gamesLogin); log.info("GamesFCServiceImpl [loginWithoutRedirect] 请求参数 {}", gamesLogin);
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("playerId", gamesLogin.getAccount()); paramsMap.put("MemberAccount", gamesLogin.getAccount());
paramsMap.put("platType", NGPlatforms.PG.getCode()); paramsMap.put("GameID", gamesLogin.getGameId());
paramsMap.put("currency", gamesLogin.getCurrency()); paramsMap.put("LanguageID", gamesLogin.getLang());
paramsMap.put("gameType", gamesLogin.getGameType()); paramsMap.put("HomeUrl", gamesLogin.getHomeUrl());
paramsMap.put("lang", gamesLogin.getLang()); paramsMap.putAll(getKeyMap(paramsMap, gamesLogin.getAgentKey(), gamesLogin.getCurrency(), gamesLogin.getAgentId()));
paramsMap.put("gameCode", gamesLogin.getGameId()); ApiFCLoginResponseDTO apiFCLoginResponseDTO = FCClient.loginWithoutRedirect(paramsMap);
paramsMap.put("returnUrl", gamesLogin.getHomeUrl()); if (this.getIsSuccess(apiFCLoginResponseDTO.getResult())) {
paramsMap.put("ingress", PlatformHomeType.WEB.getValue().equals(gamesLogin.getPlatform()) ? IngressType.PC_WEB.getValue() : IngressType.MOBILE_WEB.getValue()); return apiFCLoginResponseDTO.getUrl();
Map<String, String> headerMap =new HashMap<>();
ApiNGResponseDTO<ApiLoginResponseDTO> apiLoginResponseDTOApiNGResponseDTO = FCClient.loginWithoutRedirect(paramsMap, headerMap);
if (this.getIsSuccess(apiLoginResponseDTOApiNGResponseDTO.getCode())) {
return apiLoginResponseDTOApiNGResponseDTO.getData().getUrl();
} else { } else {
throw new BaseException(apiLoginResponseDTOApiNGResponseDTO.getMsg()); throw new ApiException(ErrorCode.ACCOUNT_NOT_EXIST.getCode());
} }
} }
@ -275,88 +260,92 @@ public class GamesFCServiceImpl implements IGamesService {
@Transactional @Transactional
@Override @Override
public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) { public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) {
List<ApiGameInfoResponseDTO> apiGameInfoResponseDTOS = redisCache.getCacheList(CacheConstants.PG_GAMES); List<ApiFCGameListResponseDTO.GameDetails> apiGameInfoResponseDTOS = redisCache.getCacheList(CacheConstants.FC_GAMES);
if (!CollectionUtils.isEmpty(apiGameInfoResponseDTOS)) { if (!CollectionUtils.isEmpty(apiGameInfoResponseDTOS)) {
return CacheConstants.PG_GAMES; return CacheConstants.FC_GAMES;
} }
gamesBaseRequestDTO.setCurrency("CNY");
log.info("GamesNGServiceImpl [getGameList] 请求参数 {}", gamesBaseRequestDTO); log.info("GamesFCServiceImpl [getGameList] 请求参数 {}", gamesBaseRequestDTO);
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("platType", NGPlatforms.PG.getCode()); paramsMap.putAll(getKeyMap(paramsMap, gamesBaseRequestDTO.getAgentKey(), gamesBaseRequestDTO.getCurrency(), gamesBaseRequestDTO.getAgentId()));
Map<String, String> headerMap =new HashMap<>(); ApiFCGameListResponseDTO gameList = FCClient.getGameList(paramsMap);
ApiNGResponseDTO<List<ApiGameInfoResponseDTO>> gameList = FCClient.getGameList(paramsMap, headerMap); if (this.getIsSuccess(gameList.getResult())) {
if (this.getIsSuccess(gameList.getCode())) {
for (ApiGameInfoResponseDTO apiGameInfoResponseDTO : gameList.getData()) { List<ApiFCGameListResponseDTO.GameDetails> gameDetailsList = new ArrayList<>();
for (String gameTypeKey : gameList.getGetGameIconList().keySet()) {
Map<String, ApiFCGameListResponseDTO.GameDetails> integerGameDetailsMap = gameList.getGetGameIconList().get(gameTypeKey);
GamePlatform gamePlatform = GamePlatform.builder() GamePlatform gamePlatform = GamePlatform.builder()
.platformType(NGGameType.findSystemByCode(apiGameInfoResponseDTO.getGameType())) .platformType(FCGameType.findSystemByCode(gameTypeKey))
.platformCode(GamePlatforms.PG.getCode()) .platformCode(GamePlatforms.FC.getCode())
.build(); .build();
List<GamePlatform> gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform); List<GamePlatform> gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform);
//没有此平台就新增一个平台 //没有此平台就新增一个平台
if (CollectionUtils.isEmpty(gamePlatforms)) { if (CollectionUtils.isEmpty(gamePlatforms)) {
gamePlatform.setPlatformName(GamePlatforms.PG.getInfo() + NGGameType.findInfoByCode(apiGameInfoResponseDTO.getGameType())); gamePlatform.setPlatformName(GamePlatforms.FC.getInfo() + FCGameType.findInfoByCode(gameTypeKey));
gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1); gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1);
gamePlatform.setCreateBy(Constants.SYSTEM); gamePlatform.setCreateBy(Constants.SYSTEM);
gamePlatformService.insertGamePlatform(gamePlatform); gamePlatformService.insertGamePlatform(gamePlatform);
} else { } else {
gamePlatform = gamePlatforms.get(0); gamePlatform = gamePlatforms.get(0);
} }
//新增游戏
for (String gameIdKey : integerGameDetailsMap.keySet()) {
ApiFCGameListResponseDTO.GameDetails gameDetails = integerGameDetailsMap.get(gameIdKey);
Game game = Game.builder() Game game = Game.builder()
.platformId(gamePlatform.getId()) .platformId(gamePlatform.getId())
.gameCode(apiGameInfoResponseDTO.getGameCode()) .gameCode(gameIdKey)
.build(); .build();
List<Game> games = gameService.selectGameList(game); List<Game> games = gameService.selectGameList(game);
//不存在这个游戏 //不存在这个游戏
if (CollectionUtils.isEmpty(games)) { if (CollectionUtils.isEmpty(games)) {
game.setGameSourceType(apiGameInfoResponseDTO.getGameType()); game.setGameSourceType(PlatformType.ELECTRONIC.getCode());
game.setFreespin(Boolean.FALSE); game.setFreespin(Boolean.FALSE);
game.setDemoStatus(Boolean.TRUE); game.setDemoStatus(Boolean.TRUE);
game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1);
game.setGameName(apiGameInfoResponseDTO.getGameName().get("zh-hans")); game.setGameName(gameDetails.getGameNameOfChinese());
game.setCreateBy(Constants.SYSTEM); game.setCreateBy(Constants.SYSTEM);
gameService.insertGame(game); gameService.insertGame(game);
} else { } else {
game = games.get(0); game = games.get(0);
} }
apiGameInfoResponseDTO.setSystemGameId(game.getId()); gameDetails.setSystemGameId(game.getId());
Map<String, String> gameName = apiGameInfoResponseDTO.getGameName();
for (String key : gameName.keySet()) { List<GameName> gameNames = gameNameService.selectGameNameList(GameName.builder().gameId(game.getId()).gameName(gameDetails.getGameNameOfChinese()).build());
String name = gameName.get(key);
List<GameName> gameNames = gameNameService.selectGameNameList(GameName.builder().gameId(game.getId()).gameName(name).build());
if (CollectionUtils.isEmpty(gameNames)) { if (CollectionUtils.isEmpty(gameNames)) {
if ("zh-hans".equals(key)) {
gameNameService.insertGameName(GameName.builder() gameNameService.insertGameName(GameName.builder()
.gameId(game.getId()) .gameId(game.getId())
.gameName(name) .gameName(gameDetails.getGameNameOfChinese())
.langCode("zh-CN") .langCode("zh-CN")
.createBy(Constants.SYSTEM) .createBy(Constants.SYSTEM)
.build()); .build());
} else if (!"zh-hant".equals(key)) { }
GameSecretKeyLangDTO gameSecretKeyLangDTO = gameSecretKeyLangService.findGameSecretKeyLangDTO(GameSecretKeyLangDTO.builder() gameNames = gameNameService.selectGameNameList(GameName.builder().gameId(game.getId()).gameName(gameDetails.getGameNameOfEnglish()).build());
.platformCode(GamePlatforms.PG.getCode()) if (CollectionUtils.isEmpty(gameNames)) {
.lang(key)
.build());
gameNameService.insertGameName(GameName.builder() gameNameService.insertGameName(GameName.builder()
.gameId(game.getId()) .gameId(game.getId())
.gameName(name) .gameName(gameDetails.getGameNameOfEnglish())
.langCode(gameSecretKeyLangDTO.getSystemLangCode()) .langCode("en-US")
.createBy(Constants.SYSTEM) .createBy(Constants.SYSTEM)
.build()); .build());
} }
}
gameDetails.setGameId(gameIdKey);
gameDetailsList.add(gameDetails);
} }
} }
redisCache.deleteObject(CacheConstants.FC_GAMES);
redisCache.deleteObject(CacheConstants.PG_GAMES); redisCache.setCacheList(CacheConstants.FC_GAMES, gameDetailsList);
redisCache.setCacheList(CacheConstants.PG_GAMES, gameList.getData()); redisCache.expire(CacheConstants.FC_GAMES, 5L, TimeUnit.HOURS);
redisCache.expire(CacheConstants.PG_GAMES, 5L, TimeUnit.HOURS);
} else { } else {
throw new BaseException(gameList.getMsg()); throw new ApiException(ErrorCode.ERROR.getCode());
} }
return CacheConstants.PG_GAMES; return CacheConstants.FC_GAMES;
} }
/** /**
@ -368,16 +357,16 @@ public class GamesFCServiceImpl implements IGamesService {
@Override @Override
@Transactional @Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesNGServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesFCServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder() GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
.platformCode(GamePlatforms.PG.getCode()) .platformCode(GamePlatforms.FC.getCode())
.code(exchangeTransferMoneyRequestDTO.getAgentId()) .code(exchangeTransferMoneyRequestDTO.getAgentId())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()) .currency(exchangeTransferMoneyRequestDTO.getCurrency())
.build()); .build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = gameExchangeMoneyService.getTransactionId(GamePlatforms.PG.getCode(), 32); String transactionId = gameExchangeMoneyService.getTransactionId(GamePlatforms.FC.getCode(), 30);
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList( List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder() GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey()) .tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
@ -397,12 +386,17 @@ public class GamesFCServiceImpl implements IGamesService {
.currencyCode(currencyDTO.getSystemCurrency()) .currencyCode(currencyDTO.getSystemCurrency())
.memberId(member.getId()) .memberId(member.getId())
.transactionId(transactionId) .transactionId(transactionId)
.platformCode(GamePlatforms.PG.getCode()) .platformCode(GamePlatforms.FC.getCode())
.build(); .build();
exchangeMoney.setCreateBy(Constants.SYSTEM); exchangeMoney.setCreateBy(Constants.SYSTEM);
//获取余额 //获取余额
String type = TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType()) ? NGTransferType.TRANSFER_OUT.getValue() : NGTransferType.TRANSFER_IN.getValue(); String type = TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType()) ? FCTransferType.TRANSFER_OUT_ALL.getValue() : FCTransferType.TRANSFER_OUT.getValue();
BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount();
//获取当前游戏币 //获取当前游戏币
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount()) .accounts(member.getGameAccount())
@ -418,31 +412,28 @@ public class GamesFCServiceImpl implements IGamesService {
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("platType", NGPlatforms.PG.getCode()); paramsMap.put("MemberAccount", exchangeTransferMoneyRequestDTO.getAccount());
paramsMap.put("playerId", exchangeTransferMoneyRequestDTO.getAccount()); paramsMap.put("TrsID", transactionId);
paramsMap.put("currency", currencyDTO.getCurrency()); paramsMap.put("AllOut", type);
paramsMap.put("type", type); paramsMap.put("Points", amount);
paramsMap.put("amount", exchangeTransferMoneyRequestDTO.getAmount()); paramsMap.putAll(getKeyMap(paramsMap, gamesBaseRequestDTO.getAgentKey(), gamesBaseRequestDTO.getCurrency(), gamesBaseRequestDTO.getAgentId()));
paramsMap.put("orderId", transactionId);
Map<String, String> key =new HashMap<>(); ApiCFBalanceTransferResponseDTO transferResponseDTO = FCClient.exchangeTransferByAgentId(paramsMap);
ApiNGResponseDTO apiNGResponseDTO = FCClient.exchangeTransferByAgentId(paramsMap, key); if (this.getIsSuccess(transferResponseDTO.getResult())) {
if (this.getIsSuccess(apiNGResponseDTO.getCode())) {
//更新数据 //更新数据
exchangeMoney.setBalance(exchangeTransferMoneyRequestDTO.getAmount()); exchangeMoney.setBalance(transferResponseDTO.getPoints().abs());
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue()); exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setCoinBefore(NumberUtil.sub(transferResponseDTO.getAfterPoint(), exchangeMoney.getBalance()).abs());
exchangeMoney.setCoinAfter(transferResponseDTO.getAfterPoint());
exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore());
exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter());
exchangeMoney.setStatus(StatusType.SUCCESS.getValue());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney); gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
ExchangeTransferStatusRequestDTO exchangeTransferStatusRequestDTO = new ExchangeTransferStatusRequestDTO();
exchangeTransferStatusRequestDTO.setAccount(exchangeTransferMoneyRequestDTO.getAccount());
exchangeTransferStatusRequestDTO.setCurrency(currencyDTO.getCurrency());
exchangeTransferStatusRequestDTO.setOrderId(transactionId);
exchangeTransferStatusRequestDTO.setAgentId(exchangeTransferMoneyRequestDTO.getAgentId());
exchangeTransferStatusRequestDTO.setAgentKey(exchangeTransferMoneyRequestDTO.getAgentKey());
this.exchangeTransferStatus(exchangeTransferStatusRequestDTO);
} else { } else {
log.error("GamesPGServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", apiNGResponseDTO.getCode(), apiNGResponseDTO.getMsg()); log.error("GamesFCServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{}", transferResponseDTO.getResult());
throw new BaseException(apiNGResponseDTO.getMsg()); throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode());
} }
return exchangeMoney.getId(); return exchangeMoney.getId();
} }
@ -456,38 +447,7 @@ public class GamesFCServiceImpl implements IGamesService {
@Override @Override
public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("playerId", exchangeTransferMoneyRequestDTO.getAccount());
paramsMap.put("currency", exchangeTransferMoneyRequestDTO.getCurrency());
paramsMap.put("orderId", exchangeTransferMoneyRequestDTO.getOrderId());
Map<String, String> key =new HashMap<>();
ApiNGResponseDTO<ApiExchangeTransferStatusResponseDTO> apiNGResponseDTO = FCClient.exchangeTransferStatus(paramsMap, key);
if (this.getIsSuccess(apiNGResponseDTO.getCode())) {
ApiExchangeTransferStatusResponseDTO apiNGResponseDTOData = apiNGResponseDTO.getData();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.platformCode(GamePlatforms.PG.getCode())
.transactionId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
for (GameExchangeMoney exchangeMoney : gameExchangeMonies) {
//更新数据
exchangeMoney.setBalance(apiNGResponseDTOData.getAmount().abs());
exchangeMoney.setCoinBefore(NumberUtil.sub(apiNGResponseDTOData.getAfterBalance(), apiNGResponseDTOData.getAmount()));
exchangeMoney.setCoinAfter(apiNGResponseDTOData.getAfterBalance());
exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore());
exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter());
exchangeMoney.setStatus(apiNGResponseDTOData.getStatus());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
}
return Boolean.TRUE; return Boolean.TRUE;
} else {
log.error("GamesPGServiceImpl [exchangeTransferStatus]错误代码{},错误信息{}", apiNGResponseDTO.getCode(), apiNGResponseDTO.getMsg());
return Boolean.FALSE;
}
} }
@ -501,82 +461,29 @@ public class GamesFCServiceImpl implements IGamesService {
@Override @Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
GameSecretKeyCurrencyDTO gameSecretKeyDTO = new GameSecretKeyCurrencyDTO();
gameSecretKeyDTO.setPlatformCodes(NGPlatforms.getAllPlatforms());
List<GameSecretKeyCurrencyDTO> currencyDTOList = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTOList(gameSecretKeyDTO);
List<String> currencys = currencyDTOList.stream()
.map(GameSecretKeyCurrencyDTO::getCurrency)
.distinct()
.collect(Collectors.toList());
List<GameSecretKeyCurrencyDTO> gameSecretKeyCurrencies = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTOList(GameSecretKeyCurrencyDTO.builder()
Set<String> cacheSet = redisCache.getCacheSet(CacheConstants.PG_GAMES_BET_CURRENCY); .platformCode(GamePlatforms.FC.getCode())
if (CollectionUtils.isEmpty(cacheSet)) {
cacheSet = new HashSet<>();
}
//如果长度一致则清空缓存循环币种
if (cacheSet.size() >= currencys.size()) {
cacheSet = new HashSet<>();
redisCache.deleteObject(CacheConstants.PG_GAMES_BET_CURRENCY);
}
//去掉重复的
currencys.removeAll(cacheSet);
String firstCurrency = currencys.get(0);
GameSecretKeyCurrencyDTO currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
.platformCode(GamePlatforms.PG.getCode())
.currency(firstCurrency)
.build()); .build());
for (GameSecretKeyCurrency gameSecretKeyCurrency : gameSecretKeyCurrencies) {
betRecordByTimeDTO.setAgentId(currencyDTO.getCode()); String startTime = DateUtils.convertTimeZone(betRecordByTimeDTO.getStartTime(), "America/New_York", DateUtils.YYYY_MM_DD_HH_MM_SS);
betRecordByTimeDTO.setAgentKey(currencyDTO.getKey()); String endTime = DateUtils.convertTimeZone(betRecordByTimeDTO.getEndTime(), "America/New_York", DateUtils.YYYY_MM_DD_HH_MM_SS);
int pageNo = 1;
int pageSize = 2000;
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("currency", currencyDTO.getCurrency()); paramsMap.put("StartDate", startTime);
paramsMap.put("pageNo", pageNo); paramsMap.put("EndDate", endTime);
paramsMap.put("pageSize", pageSize); paramsMap.putAll(getKeyMap(paramsMap, betRecordByTimeDTO.getAgentKey(), gameSecretKeyCurrency.getCurrency(), betRecordByTimeDTO.getAgentId()));
Map<String, String> key = new HashMap<>();
ApiFCBetRecordResponseDTO betRecordByTime = FCClient.getBetRecordByTime(paramsMap);
ApiNGResponseDTO<ApiGameBetRecordPageResponseDTO> betRecordByTime = FCClient.getBetRecordByTime(paramsMap, key); if (this.getIsSuccess(betRecordByTime.getResult())) {
if (this.getIsSuccess(betRecordByTime.getCode())) {
cacheSet.add(firstCurrency);
redisCache.setCacheSet(CacheConstants.PG_GAMES_BET_CURRENCY, cacheSet);
ApiNGResponseDTO<ApiGameBetRecordPageResponseDTO> result = betRecordByTime;
AtomicInteger pageNoAtomic = new AtomicInteger(pageNo);
ApiGameBetRecordPageResponseDTO data = result.getData();
//数据组装 //数据组装
this.batchInsert(data); this.batchInsert(betRecordByTime, gameSecretKeyCurrency.getSystemCurrency(), gameSecretKeyCurrency.getCurrency());
//总页数
// 计算总页数,确保不会遗漏
int totalPage = (int) Math.ceil((double) data.getTotal() / pageSize);
// 获取下一页数据
while (pageNoAtomic.get() < totalPage && data.getTotal() > 0) {
pageNoAtomic.incrementAndGet();
//请求参数
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("currency", currencyDTO.getCurrency());
paramMap.put("pageNo", pageNoAtomic.get());
paramMap.put("pageSize", pageSize);
SleepUtil.sleep(10000);
ApiNGResponseDTO<ApiGameBetRecordPageResponseDTO> betRecordByTimePage = FCClient.getBetRecordByTime(paramMap, key);
data = betRecordByTimePage.getData();
//数据组装
this.batchInsert(data);
} }
} }
getBetRecordByHistoryTime(betRecordByTimeDTO, currencyDTO);
return Boolean.TRUE; return Boolean.TRUE;
} }
@ -584,85 +491,41 @@ public class GamesFCServiceImpl implements IGamesService {
* *
* *
* @param betRecordByTimeDTO dto * @param betRecordByTimeDTO dto
* @param currencyDTO dto * @return {@link Boolean }
*/ */
private void getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO, GameSecretKeyCurrencyDTO currencyDTO) { @Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
List<GameSecretKeyCurrencyDTO> gameSecretKeyCurrencies = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTOList(GameSecretKeyCurrencyDTO.builder()
.platformCode(GamePlatforms.FC.getCode())
.build());
//捞取指定30分钟前的数据 for (GameSecretKeyCurrency gameSecretKeyCurrency : gameSecretKeyCurrencies) {
Long startTimes = DateUtils.addOrSubtractMinutes(DateUtils.getNowDate(), -30); //必须两个小时之前的数据
Long endTimes = DateUtils.getNowDate(); long startTimeLong = DateUtils.addOrSubtractMinutes(betRecordByTimeDTO.getStartTime(), -120);
betRecordByTimeDTO.setStartTime(startTimes); long endTimeLong = DateUtils.addOrSubtractMinutes(betRecordByTimeDTO.getEndTime(), -120);
betRecordByTimeDTO.setEndTime(endTimes);
//查询一个小时内的数据一次最多15分钟
int currentMinute = java.time.LocalTime.now().getMinute(); int timeWheel = 60;
// 判断当前分钟是否是 20 分、40 分或 0 分,如果不是,跳过当前执行 while (timeWheel > 0) {
if (currentMinute != 20 && currentMinute != 40 && currentMinute != 0) { String startTime = DateUtils.convertTimeZone(startTimeLong, "America/New_York", DateUtils.YYYY_MM_DD_HH_MM_SS);
// 当前时间不是 20 分、40 分、0 分,跳过执行 String endTime = DateUtils.convertTimeZone(endTimeLong, "America/New_York", DateUtils.YYYY_MM_DD_HH_MM_SS);
return;
}
String startTime = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneId.of("Asia/Shanghai"))
.format(Instant.ofEpochMilli(betRecordByTimeDTO.getStartTime()));
String endTime = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneId.of("Asia/Shanghai"))
.format(Instant.ofEpochMilli(betRecordByTimeDTO.getEndTime()));
betRecordByTimeDTO.setAgentId(currencyDTO.getCode());
betRecordByTimeDTO.setAgentKey(currencyDTO.getKey());
int pageNo = 1;
int pageSize = 2000;
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("currency", currencyDTO.getCurrency()); paramsMap.put("StartDate", startTime);
paramsMap.put("pageNo", pageNo); paramsMap.put("EndDate", endTime);
paramsMap.put("pageSize", pageSize); paramsMap.putAll(getKeyMap(paramsMap, betRecordByTimeDTO.getAgentKey(), gameSecretKeyCurrency.getCurrency(), betRecordByTimeDTO.getAgentId()));
paramsMap.put("startTime", startTime);
paramsMap.put("endTime", endTime);
Map<String, String> key =new HashMap<>();
ApiFCBetRecordResponseDTO betRecordByTime = FCClient.getBetRecordByHistoryTime(paramsMap);
ApiNGResponseDTO<ApiGameBetRecordPageResponseDTO> betRecordByTime = FCClient.getBetRecordByHistoryTime(paramsMap, key); if (this.getIsSuccess(betRecordByTime.getResult())) {
if (this.getIsSuccess(betRecordByTime.getCode())) {
ApiNGResponseDTO<ApiGameBetRecordPageResponseDTO> result = betRecordByTime;
AtomicInteger pageNoAtomic = new AtomicInteger(pageNo);
threadPoolTaskExecutor.execute(() -> {
ApiGameBetRecordPageResponseDTO data = result.getData();
//数据组装 //数据组装
this.batchInsert(data); this.batchInsert(betRecordByTime, gameSecretKeyCurrency.getSystemCurrency(), gameSecretKeyCurrency.getCurrency());
}
//总页数 timeWheel -= 15;
// 计算总页数,确保不会遗漏
int totalPage = (int) Math.ceil((double) data.getTotal() / pageSize);
// 获取下一页数据
while (pageNoAtomic.get() < totalPage && data.getTotal() > 0) {
pageNoAtomic.incrementAndGet();
//请求参数
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("currency", currencyDTO.getCurrency());
paramMap.put("pageNo", pageNoAtomic.get());
paramMap.put("pageSize", pageSize);
paramMap.put("startTime", startTime);
paramMap.put("endTime", endTime);
SleepUtil.sleep(10000);
ApiNGResponseDTO<ApiGameBetRecordPageResponseDTO> betRecordByTimePage = FCClient.getBetRecordByTime(paramMap, key);
data = betRecordByTimePage.getData();
//数据组装
this.batchInsert(data);
} }
});
} }
return Boolean.TRUE;
} }
@ -705,8 +568,16 @@ public class GamesFCServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) { public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) {
log.info("GamesFCServiceImpl [kickMember] 请求参数 {}", kickMemberRequestDTO);
return null; Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("MemberAccount", kickMemberRequestDTO.getAccount());
paramsMap.putAll(getKeyMap(paramsMap, kickMemberRequestDTO.getAgentKey(), kickMemberRequestDTO.getCurrency(), kickMemberRequestDTO.getAgentId()));
ApiFCResult apiFCResult = FCClient.kickMember(paramsMap);
if (this.getIsSuccess(apiFCResult.getResult())) {
return Boolean.TRUE;
} else {
throw new ApiException(ErrorCode.KICK_OUT_AILED.getCode());
}
} }
/** /**
@ -717,8 +588,15 @@ public class GamesFCServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) { public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) {
log.info("GamesFCServiceImpl [kickMemberAll] 请求参数 {}", kickMemberAllDTO);
return null; Map<String, Object> paramsMap = new HashMap<>();
paramsMap.putAll(getKeyMap(paramsMap, kickMemberAllDTO.getAgentKey(), kickMemberAllDTO.getCurrency(), kickMemberAllDTO.getAgentId()));
ApiFCResult apiFCResult = FCClient.kickMemberAll(paramsMap);
if (this.getIsSuccess(apiFCResult.getResult())) {
return Boolean.TRUE;
} else {
throw new ApiException(ErrorCode.KICK_OUT_AILED.getCode());
}
} }
/** /**
@ -743,7 +621,7 @@ public class GamesFCServiceImpl implements IGamesService {
@Override @Override
public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) { public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) {
return null; return Boolean.FALSE;
} }
@ -757,66 +635,49 @@ public class GamesFCServiceImpl implements IGamesService {
public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) { public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) {
//转化类 //转化类
ApiGameBetRecordPageResponseDTO.GameBetRecord resultBean = (ApiGameBetRecordPageResponseDTO.GameBetRecord) gamesDataBuildDTO.getData(); ApiFCBetRecordResponseDTO.BetRecord resultBean = (ApiFCBetRecordResponseDTO.BetRecord) gamesDataBuildDTO.getData();
NGPlatforms ngPlatforms = NGPlatforms.getByCode(resultBean.getPlatType());
if (ObjectUtils.isEmpty(ngPlatforms)) {
return null;
}
String platform = ngPlatforms.getPlatform(); Member member = memberService.selectMemberByGameAccount(resultBean.getAccount());
List<Game> games = gameService.selectGameDTOList(GameDTO.builder().gameName(resultBean.getGameName()).platformCode(platform).build());
if (CollectionUtils.isEmpty(games)) {
return null;
}
Game gamesDataDTO = games.get(0);
GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
.platformCodes(NGPlatforms.getAllPlatforms())
.currency(resultBean.getCurrency())
.build());
Member member = memberService.selectMemberByGameAccount(resultBean.getPlayerId());
if (ObjectUtils.isEmpty(member)) { if (ObjectUtils.isEmpty(member)) {
return null; return null;
} }
GameDTO gameDTO = new GameDTO(); List<ApiFCGameListResponseDTO.GameDetails> gamesDatas = redisCache.getCacheList(CacheConstants.FC_GAMES);
gameDTO.setPlatformCodes(NGPlatforms.getAllPlatforms()); Map<String, ApiFCGameListResponseDTO.GameDetails> dataDTOMap = gamesDatas.stream().collect(Collectors.toMap(ApiFCGameListResponseDTO.GameDetails::getGameId, e -> e));
ApiFCGameListResponseDTO.GameDetails gamesDataDTO = dataDTOMap.get(resultBean.getGameID());
int gameStatus = GameStatus.FLAT.getCode(); // 判断输赢
if (BigDecimal.ZERO.compareTo(resultBean.getSettledAmount()) > 0) { Integer gameStatus = GameStatus.FLAT.getCode();
if (BigDecimal.ZERO.compareTo(resultBean.getWinlose()) > 0) {
gameStatus = GameStatus.FAIL.getCode(); gameStatus = GameStatus.FAIL.getCode();
} else if (BigDecimal.ZERO.compareTo(resultBean.getSettledAmount()) < 0) { } else if (BigDecimal.ZERO.compareTo(resultBean.getWinlose()) < 0) {
gameStatus = GameStatus.WIN.getCode(); gameStatus = GameStatus.WIN.getCode();
} }
//数据构造 //数据构造
GameBettingDetails gameBettingDetails = GameBettingDetails.builder() GameBettingDetails gameBettingDetails = GameBettingDetails.builder()
.tenantKey(member.getTenantKey()) .tenantKey(member.getTenantKey())
//保存我们的币种id //保存我们的币种id
.currencyCode(currencyDTO.getSystemCurrency()) .currencyCode(gamesDataBuildDTO.getSystemCurrencyCode())
.memberId(member.getId()) .memberId(member.getId())
.gameCode(gamesDataDTO.getGameCode()) .gameCode(resultBean.getGameID())
.gameType(NGGameType.findSystemByCode(resultBean.getGameType())) .gameType(FCGameType.findSystemByCode(resultBean.getGametype()))
.platformCode(NGPlatforms.getByCode(resultBean.getPlatType()).getPlatform()) .platformCode(GamePlatforms.FC.getCode())
.gameId(gamesDataDTO.getId()) .gameId(gamesDataDTO.getSystemGameId())
.gameName(gamesDataDTO.getGameName()) .gameName(gamesDataDTO.getGameNameOfChinese())
.gameStatus(gameStatus) .gameStatus(gameStatus)
.gameStatusType(1) .gameStatusType(1)
.gameCurrencyCode(resultBean.getCurrency()) .gameCurrencyCode(gamesDataBuildDTO.getCurrencyCode())
.account(resultBean.getPlayerId()) .account(resultBean.getAccount())
.wagersId(resultBean.getGameOrderId()) .wagersId(resultBean.getRecordID())
.wagersTime(resultBean.getBetTime().getTime()) .wagersTime(resultBean.getBdate().getTime())
.betAmount(resultBean.getBetAmount().abs()) .betAmount(resultBean.getBet())
.payoffTime(resultBean.getLastUpdateTime().getTime()) .payoffTime(resultBean.getBdate().getTime())
.payoffAmount(resultBean.getSettledAmount().abs()) .payoffAmount(resultBean.getWinlose().abs())
.settlementTime(resultBean.getLastUpdateTime().getTime()) .settlementTime(resultBean.getBdate().getTime())
.turnover(resultBean.getValidAmount()) .turnover(resultBean.getValidBet())
.orderNo(StringUtils.isNotEmpty(resultBean.getRound()) ? String.valueOf(resultBean.getRound()) : null) .settlementStatus(SettlementStatusEnum.COMPLETED.getCode())
.settlementStatus(NGSettlementStatusEnum.fromStatus(resultBean.getStatus()).getCode())
.round(resultBean.getRound())
.table(resultBean.getTable())
.seat(resultBean.getSeat())
.betContent(resultBean.getBetContent())
.build(); .build();
gameBettingDetails.setCreateBy(Constants.SYSTEM); gameBettingDetails.setCreateBy(Constants.SYSTEM);
gameBettingDetails.setCreateTime(DateUtils.getNowDate()); gameBettingDetails.setCreateTime(DateUtils.getNowDate());
@ -824,33 +685,33 @@ public class GamesFCServiceImpl implements IGamesService {
} }
/** /**
* *
* *
* @param data * @param data
* @param systemCurrencyCode
*/ */
private synchronized void batchInsert(ApiGameBetRecordPageResponseDTO data) { private synchronized void batchInsert(ApiFCBetRecordResponseDTO data, String systemCurrencyCode, String currencyCode) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>(); List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<Long> wagersIds = new ArrayList<>(); List<String> wagersIds = new ArrayList<>();
//数据转化 //数据转化
for (ApiGameBetRecordPageResponseDTO.GameBetRecord bean : data.getList()) { for (ApiFCBetRecordResponseDTO.BetRecord bean : data.getRecords()) {
GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).build()); GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).currencyCode(currencyCode).systemCurrencyCode(systemCurrencyCode).build());
if (!ObjectUtils.isEmpty(bettingDetails)) { if (!ObjectUtils.isEmpty(bettingDetails)) {
bettingDetails.setId(IdUtil.getSnowflakeNextId()); bettingDetails.setId(IdUtil.getSnowflakeNextId());
gameBettingDetails.add(bettingDetails); gameBettingDetails.add(bettingDetails);
} }
wagersIds.add(bean.getGameOrderId()); wagersIds.add(bean.getRecordID());
} }
if (!CollectionUtils.isEmpty(gameBettingDetails)) { if (!CollectionUtils.isEmpty(gameBettingDetails)) {
//查询重复数据id //查询重复数据id
List<Long> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds); List<String> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds);
//用steam流清除list中与wagersIds集合相同的数据 //用steam流清除list中与wagersIds集合相同的数据
gameBettingDetails = gameBettingDetails.stream() gameBettingDetails = gameBettingDetails.stream()
.filter(detail -> !removeWagersIds.contains(detail.getWagersId())) .filter(detail -> !removeWagersIds.contains(detail.getWagersId()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!CollectionUtils.isEmpty(gameBettingDetails)) { if (!CollectionUtils.isEmpty(gameBettingDetails)) {
List<Long> wagersId = gameBettingDetails.stream().map(GameBettingDetails::getWagersId).collect(Collectors.toList());
gameBettingDetailsService.deleteGameBettingDetailsByWagersId(wagersId);
gameBettingDetailsService.batchInsert(gameBettingDetails); gameBettingDetailsService.batchInsert(gameBettingDetails);
} }
} }

View File

@ -25,7 +25,7 @@ public class JILIBetRecordDataResponseDTO {
* id * id
*/ */
@JsonProperty("WagersId") @JsonProperty("WagersId")
private long wagersId; private String wagersId;
/** /**
* id * id
*/ */

View File

@ -436,6 +436,19 @@ public class GamesJILIServiceImpl implements IGamesService {
return Boolean.TRUE; return Boolean.TRUE;
} }
/**
*
*
* @param betRecordByTimeDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
return null;
}
/** /**
* *
* *
@ -688,7 +701,7 @@ public class GamesJILIServiceImpl implements IGamesService {
*/ */
private void batchInsert(JILIBetRecordResponseDTO betRecordJILIResponse) { private void batchInsert(JILIBetRecordResponseDTO betRecordJILIResponse) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>(); List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<Long> wagersIds = new ArrayList<>(); List<String> wagersIds = new ArrayList<>();
//数据组装 //数据组装
JILIBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData(); JILIBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData();
//数据转化 //数据转化
@ -702,7 +715,7 @@ public class GamesJILIServiceImpl implements IGamesService {
} }
if (!CollectionUtils.isEmpty(gameBettingDetails)) { if (!CollectionUtils.isEmpty(gameBettingDetails)) {
//查询重复数据id //查询重复数据id
List<Long> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds); List<String> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds);
//用steam流清除list中与wagersIds集合相同的数据 //用steam流清除list中与wagersIds集合相同的数据
gameBettingDetails = gameBettingDetails.stream() gameBettingDetails = gameBettingDetails.stream()
.filter(detail -> !removeWagersIds.contains(detail.getWagersId())) .filter(detail -> !removeWagersIds.contains(detail.getWagersId()))

View File

@ -637,6 +637,16 @@ public class GamesPGServiceImpl implements IGamesService {
} }
} }
/**
*
*
* @param betRecordByTimeDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
return null;
}
/** /**
@ -777,7 +787,7 @@ public class GamesPGServiceImpl implements IGamesService {
.gameStatusType(1) .gameStatusType(1)
.gameCurrencyCode(resultBean.getCurrency()) .gameCurrencyCode(resultBean.getCurrency())
.account(resultBean.getPlayerId()) .account(resultBean.getPlayerId())
.wagersId(resultBean.getGameOrderId()) .wagersId(String.valueOf(resultBean.getGameOrderId()))
.wagersTime(resultBean.getBetTime().getTime()) .wagersTime(resultBean.getBetTime().getTime())
.betAmount(resultBean.getBetAmount().abs()) .betAmount(resultBean.getBetAmount().abs())
.payoffTime(resultBean.getLastUpdateTime().getTime()) .payoffTime(resultBean.getLastUpdateTime().getTime())
@ -804,7 +814,7 @@ public class GamesPGServiceImpl implements IGamesService {
*/ */
private synchronized void batchInsert(ApiGameBetRecordPageResponseDTO data) { private synchronized void batchInsert(ApiGameBetRecordPageResponseDTO data) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>(); List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<Long> wagersIds = new ArrayList<>(); List<String> wagersIds = new ArrayList<>();
//数据转化 //数据转化
for (ApiGameBetRecordPageResponseDTO.GameBetRecord bean : data.getList()) { for (ApiGameBetRecordPageResponseDTO.GameBetRecord bean : data.getList()) {
GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).build()); GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).build());
@ -812,17 +822,17 @@ public class GamesPGServiceImpl implements IGamesService {
bettingDetails.setId(IdUtil.getSnowflakeNextId()); bettingDetails.setId(IdUtil.getSnowflakeNextId());
gameBettingDetails.add(bettingDetails); gameBettingDetails.add(bettingDetails);
} }
wagersIds.add(bean.getGameOrderId()); wagersIds.add(String.valueOf(bean.getGameOrderId()));
} }
if (!CollectionUtils.isEmpty(gameBettingDetails)) { if (!CollectionUtils.isEmpty(gameBettingDetails)) {
//查询重复数据id //查询重复数据id
List<Long> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds); List<String> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds);
//用steam流清除list中与wagersIds集合相同的数据 //用steam流清除list中与wagersIds集合相同的数据
gameBettingDetails = gameBettingDetails.stream() gameBettingDetails = gameBettingDetails.stream()
.filter(detail -> !removeWagersIds.contains(detail.getWagersId())) .filter(detail -> !removeWagersIds.contains(detail.getWagersId()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!CollectionUtils.isEmpty(gameBettingDetails)) { if (!CollectionUtils.isEmpty(gameBettingDetails)) {
List<Long> wagersId = gameBettingDetails.stream().map(GameBettingDetails::getWagersId).collect(Collectors.toList()); List<String> wagersId = gameBettingDetails.stream().map(GameBettingDetails::getWagersId).collect(Collectors.toList());
gameBettingDetailsService.deleteGameBettingDetailsByWagersId(wagersId); gameBettingDetailsService.deleteGameBettingDetailsByWagersId(wagersId);
gameBettingDetailsService.batchInsert(gameBettingDetails); gameBettingDetailsService.batchInsert(gameBettingDetails);
} }

View File

@ -24,6 +24,15 @@ public class GamesDataBuildDTO
*/ */
private Object data; private Object data;
/**
*
*/
private String systemCurrencyCode;
/**
*
*/
private String currencyCode;
} }

View File

@ -23,7 +23,7 @@ public class GetGameDetailRequestDTO extends GamesBaseRequestDTO {
/** /**
* id * id
*/ */
private Long wagersId; private String wagersId;
/** /**
* *
*/ */

View File

@ -444,6 +444,17 @@ public class GamesXKServiceImpl implements IGamesService {
} }
/**
*
*
* @param betRecordByTimeDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
return null;
}
/** /**
* *
* *
@ -532,7 +543,7 @@ public class GamesXKServiceImpl implements IGamesService {
*/ */
private void batchInsert(XKBetRecordResponseDTO xkBetRecordResponseDTO) { private void batchInsert(XKBetRecordResponseDTO xkBetRecordResponseDTO) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>(); List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<Long> wagersIds = new ArrayList<>(); List<String> wagersIds = new ArrayList<>();
//数据组装 //数据组装
XKBetRecordResponseDTO.DataBean dataBean = xkBetRecordResponseDTO.getData(); XKBetRecordResponseDTO.DataBean dataBean = xkBetRecordResponseDTO.getData();
//数据转化 //数据转化
@ -542,11 +553,11 @@ public class GamesXKServiceImpl implements IGamesService {
bettingDetails.setId(IdUtil.getSnowflakeNextId()); bettingDetails.setId(IdUtil.getSnowflakeNextId());
gameBettingDetails.add(bettingDetails); gameBettingDetails.add(bettingDetails);
} }
wagersIds.add(bean.getWagersId()); wagersIds.add(String.valueOf(bean.getWagersId()));
} }
if (!CollectionUtils.isEmpty(gameBettingDetails)) { if (!CollectionUtils.isEmpty(gameBettingDetails)) {
//查询重复数据id //查询重复数据id
List<Long> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds); List<String> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds);
//用steam流清除list中与wagersIds集合相同的数据 //用steam流清除list中与wagersIds集合相同的数据
gameBettingDetails = gameBettingDetails.stream() gameBettingDetails = gameBettingDetails.stream()
.filter(detail -> !removeWagersIds.contains(detail.getWagersId())) .filter(detail -> !removeWagersIds.contains(detail.getWagersId()))
@ -603,7 +614,7 @@ public class GamesXKServiceImpl implements IGamesService {
.gameStatusType(resultBean.getType()) .gameStatusType(resultBean.getType())
.gameCurrencyCode(resultBean.getAgentId()) .gameCurrencyCode(resultBean.getAgentId())
.account(String.valueOf(resultBean.getAccount())) .account(String.valueOf(resultBean.getAccount()))
.wagersId(resultBean.getWagersId()) .wagersId(String.valueOf(resultBean.getWagersId()))
.wagersTime(resultBean.getWagersTime()) .wagersTime(resultBean.getWagersTime())
.betAmount(resultBean.getBetAmount().abs()) .betAmount(resultBean.getBetAmount().abs())
.payoffTime(resultBean.getPayoffTime()) .payoffTime(resultBean.getPayoffTime())

View File

@ -116,8 +116,7 @@ public class GameBettingDetails extends BaseEntity
/** 游戏注单唯一值 */ /** 游戏注单唯一值 */
@Excel(name = "游戏注单唯一值") @Excel(name = "游戏注单唯一值")
@JsonSerialize(using = ToStringSerializer.class) private String wagersId;
private Long wagersId;
/** 投注时间 (Unix 时间戳) */ /** 投注时间 (Unix 时间戳) */
@Excel(name = "投注时间 (Unix 时间戳)") @Excel(name = "投注时间 (Unix 时间戳)")

View File

@ -36,7 +36,7 @@ public class GamePlatform extends BaseEntity
@Excel(name = "平台编码") @Excel(name = "平台编码")
private String platformCode; private String platformCode;
/** 平台类型 ff_game_type 字典 */ /** 平台类型 ff_game_platform_type 字典 */
@Excel(name = "平台类型 ff_game_platform_type 字典") @Excel(name = "平台类型 ff_game_platform_type 字典")
private Integer platformType; private Integer platformType;

View File

@ -29,7 +29,7 @@ public interface GameBettingDetailsMapper
* @param wagersIds ID * @param wagersIds ID
* @return {@link List }<{@link Long }> * @return {@link List }<{@link Long }>
*/ */
List<Long> selectGameBettingDetailsByWagersId(@Param("wagersIds") List<Long> wagersIds); List<String> selectGameBettingDetailsByWagersId(@Param("wagersIds") List<String> wagersIds);
/** /**
@ -87,5 +87,5 @@ public interface GameBettingDetailsMapper
* @param wagersIds id * @param wagersIds id
* @return int * @return int
*/ */
int deleteGameBettingDetailsByWagersId(@Param("wagersIds") List<Long> wagersIds); int deleteGameBettingDetailsByWagersId(@Param("wagersIds") List<String> wagersIds);
} }

View File

@ -29,7 +29,7 @@ public interface IGameBettingDetailsService
* @param wagersIds ID * @param wagersIds ID
* @return {@link List }<{@link Long }> * @return {@link List }<{@link Long }>
*/ */
List<Long> selectGameBettingDetailsByWagersId(List<Long> wagersIds); List<String> selectGameBettingDetailsByWagersId(List<String> wagersIds);
@ -89,5 +89,5 @@ public interface IGameBettingDetailsService
* @param wagersId id * @param wagersId id
* @return int * @return int
*/ */
int deleteGameBettingDetailsByWagersId(List<Long> wagersId); int deleteGameBettingDetailsByWagersId(List<String> wagersId);
} }

View File

@ -43,7 +43,7 @@ public class GameBettingDetailsServiceImpl implements IGameBettingDetailsService
* @return {@link List }<{@link Long }> * @return {@link List }<{@link Long }>
*/ */
@Override @Override
public List<Long> selectGameBettingDetailsByWagersId(List<Long> wagersIds) { public List<String> selectGameBettingDetailsByWagersId(List<String> wagersIds) {
return gameBettingDetailsMapper.selectGameBettingDetailsByWagersId(wagersIds); return gameBettingDetailsMapper.selectGameBettingDetailsByWagersId(wagersIds);
} }
@ -128,7 +128,7 @@ public class GameBettingDetailsServiceImpl implements IGameBettingDetailsService
* @return int * @return int
*/ */
@Override @Override
public int deleteGameBettingDetailsByWagersId(List<Long> wagersId) { public int deleteGameBettingDetailsByWagersId(List<String> wagersId) {
return gameBettingDetailsMapper.deleteGameBettingDetailsByWagersId(wagersId); return gameBettingDetailsMapper.deleteGameBettingDetailsByWagersId(wagersId);
} }
} }

View File

@ -5,6 +5,7 @@ import com.ff.base.core.redis.RedisCache;
import com.ff.base.datasource.DynamicDataSourceContextHolder; import com.ff.base.datasource.DynamicDataSourceContextHolder;
import com.ff.base.enums.GamePlatforms; import com.ff.base.enums.GamePlatforms;
import com.ff.base.enums.NGPlatforms; import com.ff.base.enums.NGPlatforms;
import com.ff.base.enums.PlatformType;
import com.ff.base.enums.StatusType; import com.ff.base.enums.StatusType;
import com.ff.base.utils.DateUtils; import com.ff.base.utils.DateUtils;
import com.ff.game.api.IGamesService; import com.ff.game.api.IGamesService;
@ -91,7 +92,8 @@ public class GameTask {
for (String gameKey : gamesService.keySet()) { for (String gameKey : gamesService.keySet()) {
String platformCode = gameKey.replace(Constants.SERVICE, ""); String platformCode = gameKey.replace(Constants.SERVICE, "");
if (NGPlatforms.exists(platformCode)) { //特殊的平台跳过
if (NGPlatforms.exists(platformCode)|| GamePlatforms.FC.getInfo().equals(platformCode)) {
continue; continue;
} }
@ -120,6 +122,94 @@ public class GameTask {
} }
/**
* cfbetting
*/
public void insertGameCFBettingDetails(Integer backTime) {
try {
//捞取指定分钟前的数据
Long startTime = DateUtils.addOrSubtractMinutes(DateUtils.getNowDate(), backTime);
Long endTime = DateUtils.getNowDate();
for (String gameKey : gamesService.keySet()) {
String platformCode = gameKey.replace(Constants.SERVICE, "");
//不是特殊的平台跳过
if (!GamePlatforms.FC.getInfo().equals(platformCode)) {
continue;
}
List<GameSecretKey> gameSecretKeys = gameSecretKeyService.selectGameSecretKeyList(GameSecretKey.builder().platform(platformCode).build());
for (GameSecretKey gameSecretKey : gameSecretKeys) {
try {
gamesService.get(gameKey).getGameList(GamesBaseRequestDTO.builder()
.agentId(gameSecretKey.getCode())
.agentKey(gameSecretKey.getKey())
.build());
BetRecordByTimeDTO betRecordByTimeDTO = new BetRecordByTimeDTO();
betRecordByTimeDTO.setGamePlatform(gameSecretKey.getPlatform());
betRecordByTimeDTO.setStartTime(startTime);
betRecordByTimeDTO.setEndTime(endTime);
betRecordByTimeDTO.setPage(1);
betRecordByTimeDTO.setPageLimit(1000);
betRecordByTimeDTO.setAgentId(gameSecretKey.getCode());
betRecordByTimeDTO.setAgentKey(gameSecretKey.getKey());
gamesService.get(gameKey).getBetRecordByTime(betRecordByTimeDTO);
} catch (Exception e) {
log.error("查询 平台 {} 投注记录失败,错误信息 {}", gameSecretKey.getCode(), e);
}
}
}
} catch (Exception e) {
log.error("查询 FC 投注记录失败,错误信息 {}", e);
}
}
/**
* 使
*
* @param backTime
*/
public void insertHistoryGameBettingDetails(Integer backTime) {
//捞取指定分钟前的数据
Long startTime = DateUtils.addOrSubtractMinutes(DateUtils.getNowDate(), backTime);
Long endTime = DateUtils.getNowDate();
for (String gameKey : gamesService.keySet()) {
String platformCode = gameKey.replace(Constants.SERVICE, "");
List<GameSecretKey> gameSecretKeys = gameSecretKeyService.selectGameSecretKeyList(GameSecretKey.builder().platform(platformCode).build());
for (GameSecretKey gameSecretKey : gameSecretKeys) {
try {
gamesService.get(gameKey).getGameList(GamesBaseRequestDTO.builder()
.agentId(gameSecretKey.getCode())
.agentKey(gameSecretKey.getKey())
.build());
BetRecordByTimeDTO betRecordByTimeDTO = new BetRecordByTimeDTO();
betRecordByTimeDTO.setGamePlatform(gameSecretKey.getPlatform());
betRecordByTimeDTO.setStartTime(startTime);
betRecordByTimeDTO.setEndTime(endTime);
betRecordByTimeDTO.setPage(1);
betRecordByTimeDTO.setPageLimit(1000);
betRecordByTimeDTO.setAgentId(gameSecretKey.getCode());
betRecordByTimeDTO.setAgentKey(gameSecretKey.getKey());
gamesService.get(gameKey).getBetRecordByHistoryTime(betRecordByTimeDTO);
} catch (Exception e) {
log.error("查询 平台 {} 投注记录失败,错误信息 {}", gameSecretKey.getCode(), e);
}
}
}
}
/** /**
* ngbetting * ngbetting
*/ */

View File

@ -89,7 +89,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select> </select>
<select id="selectGameBettingDetailsByWagersId" resultType="java.lang.Long"> <select id="selectGameBettingDetailsByWagersId" resultType="java.lang.String">
select wagers_id from ff_game_betting_details select wagers_id from ff_game_betting_details
where wagers_id in where wagers_id in