Compare commits

..

No commits in common. "d2ced1154d1e7c759eb591bb61ebb6fdfa7ee3c1" and "f35179c8bcff0654e7e2d5983db84597e46c4219" have entirely different histories.

161 changed files with 1279 additions and 9347 deletions

View File

@ -51,10 +51,7 @@ public class CacheConstants {
*/ */
public static final String XK_GAMES = "xk_games:"; public static final String XK_GAMES = "xk_games:";
/**
* ae
*/
public static final String AE_GAMES = "ae_games:";
/** /**
* km * km
*/ */
@ -71,11 +68,6 @@ public class CacheConstants {
*/ */
public static final String PG_GAMES = "pg_games:"; public static final String PG_GAMES = "pg_games:";
/**
* pgt
*/
public static final String PGT_GAMES = "pgt_games:";
/** /**
* fc * fc
@ -92,26 +84,11 @@ public class CacheConstants {
* dg * dg
*/ */
public static final String DG_GAMES = "dg_games:"; public static final String DG_GAMES = "dg_games:";
/**
* fb
*/
public static final String FB_Sports = "fp_sports:";
/**
* db
*/
public static final String DB_Sports = "db_sports:";
/** /**
* pg * 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";
/**
* pgtid
*/
public static final String PGT_NEXT_ID = "pgt_next:id:";
/** /**
* ae * ae
*/ */
@ -130,15 +107,6 @@ public class CacheConstants {
*/ */
public static final String KM_USER_TOKEN = "km:user:token:"; public static final String KM_USER_TOKEN = "km:user:token:";
/**
* ae
*/
public static final String SV388_TIME_FROM= "sv388:time:from";
public static final String SV388_GAMES = "sv388_games:";
} }

View File

@ -20,8 +20,8 @@ public enum ErrorCode {
CURRENCY_NOT_EXIST(1004, "游戏平台不支持的货币"), CURRENCY_NOT_EXIST(1004, "游戏平台不支持的货币"),
GAME_NOT_EXIST(1005, "游戏不存在"), GAME_NOT_EXIST(1005, "游戏不存在"),
CURRENCY_EXCHANGE(1006, "不支持币种的汇率"), CURRENCY_EXCHANGE(1006, "不支持币种的汇率"),
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, "玩家游玩中"), PLAYERS_ARE_PLAYING(1011, "玩家游玩中"),
@ -30,14 +30,6 @@ public enum ErrorCode {
ACCOUNT_NOT_ONLINE(1014, "账号不在线"), ACCOUNT_NOT_ONLINE(1014, "账号不在线"),
FREQUENT_BALANCE_TRANSFER(1015, "当前游戏账号余额转移频繁"), FREQUENT_BALANCE_TRANSFER(1015, "当前游戏账号余额转移频繁"),
PLATFORM_NOT_METHODS(1016, "游戏平台不支持的方法"), PLATFORM_NOT_METHODS(1016, "游戏平台不支持的方法"),
Create_Member_Failure(1017, "创建会员失败"),
Transfer_In_Failure(1018, "转入失败"),
Transfer_Out_Failure(1019, "转出失败"),
Get_Member_Info_Failure(1020, "获取会员信息失败"),
Transfer_Not_Exist(1021, "转帐操作不存在"),
Get_Url_Failure(1022, "获取URL失败"),
Miss_Config(1023, "缺少配置"),
DUPLICATE_ORDER_ID (1024, "重复的订单id"),
; ;
// 获取错误码 // 获取错误码

View File

@ -1,60 +0,0 @@
package com.ff.base.enums;
import lombok.Getter;
import java.util.Optional;
import java.util.stream.Stream;
/**
* xkgame
*
* @author shi
* @date 2024/11/13
*/
@Getter
public enum FBSportsType {
Sports("8", 8,"FB体育"),
;
private final String code;
private final Integer systemCode;
private final String info;
FBSportsType(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(FBSportsType.values())
.filter(gameType -> gameType.getCode().equals(code))
.map(FBSportsType::getSystemCode)
.findFirst();
return system.orElse(null);
}
/**
*
*
* @param code
* @return {@link String }
*/
public static String findInfoByCode(String code) {
Optional<String> system = Stream.of(FBSportsType.values())
.filter(gameType -> gameType.getCode().equals(code))
.map(FBSportsType::getInfo)
.findFirst();
return system.orElse(null);
}
}

View File

@ -1,34 +0,0 @@
package com.ff.base.enums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
/**
*
*
* @author shi
* @date 2025/04/08
*/
@Getter
@AllArgsConstructor
public enum GameExchangeStep {
CREATE_ORDER(1, "创建订单"),
DEDUCT_BALANCE(2, "转入提前扣租户余额"),
PLATFORM_TRANSACTION(3, "平台交易成功"),
TENANT_QUOTA_DEDUCTED(4, "转出租户额度增加成功");
private final Integer code;
private final String description;
// 根据 code 获取对应的枚举
public static GameExchangeStep getByCode(int code) {
for (GameExchangeStep step : GameExchangeStep.values()) {
if (step.getCode() == code) {
return step;
}
}
return null;
}
}

View File

@ -1,21 +0,0 @@
package com.ff.base.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author shi
* @date 2025/04/08
*/
@Getter
@AllArgsConstructor
public enum GameExchangeStepStatus {
IN_PROGRESS(0, "进行中"),
SUCCESS(1, "成功"),
FAILURE(2, "失败");
private final int code;
private final String description;
}

View File

@ -1,7 +1,5 @@
package com.ff.base.enums; package com.ff.base.enums;
import com.ff.base.exception.base.ApiException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -15,11 +13,8 @@ public enum GamePlatforms {
DG("DG", "DG"), DG("DG", "DG"),
MT("MT", "美天棋牌"), MT("MT", "美天棋牌"),
AE("AE", "AE"), AE("AE", "AE"),
KM("KM", "KM"), KM("KM", "KM")
PGT("PGT", "PGT"), ;
FBSports("FBSports", "FB体育"),
SV388("SV388", "SV388真人"),
DBSports("DBSports", "DB体育");
private final String code; private final String code;
private final String info; private final String info;
@ -29,20 +24,6 @@ public enum GamePlatforms {
this.info = info; this.info = info;
} }
/**
*
*
* @param code
* @return {@link GamePlatforms }
*/
public static GamePlatforms getByCode(String code) {
for (GamePlatforms platform : GamePlatforms.values()) {
if (platform.getCode().equals(code)) {
return platform;
}
}
throw new ApiException(ErrorCode.PLATFORM_NOT_EXIST.getCode());
}
public static List<String> getCodes() { public static List<String> getCodes() {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();

View File

@ -1,24 +0,0 @@
package com.ff.base.enums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
/**
*
*
* @author shi
* @date 2025/04/07
*/
@Getter
@AllArgsConstructor
public enum PGTBetStatus {
OPEN(1, "打开 或 未结算", "OPEN"),
SETTLED(2, "已结算", "SETTLED"),
UNSETTLED(1, "未结算", "UNSETTLED"),
VOID(3, "作废 或 无效", "VOID");
private final int code;
private final String description;
private final String type;
}

View File

@ -1,43 +0,0 @@
package com.ff.base.enums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import java.util.Optional;
import java.util.stream.Stream;
/**
* pgt
*
* @author shi
* @date 2025/04/07
*/
@Getter
@AllArgsConstructor
public enum PGTGameType {
EGAMES("EGAMES",1, "游戏老虎机"),
LIVECASINO("LIVECASINO",2, "现场赌场"),
SPORT("SPORT",8, "体育"),
POKER("POKER",2, "扑克"),
TRADING("TRADING",1, "贸易");
// 枚举字段
private final String code;
private final Integer systemCode;
private final String description;
/**
*
*
* @param code
* @return {@link Integer }
*/
public static Integer findSystemByCode(String code) {
Optional<Integer> system = Stream.of(PGTGameType.values())
.filter(gameType -> gameType.getCode().equals(code))
.map(PGTGameType::getSystemCode)
.findFirst();
return system.orElse(null);
}
}

View File

@ -1,35 +0,0 @@
package com.ff.base.enums;
import com.dtflys.forest.annotation.Get;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
/**
* pgtplayout
*
* @author shi
* @date 2025/04/07
*/
@Getter
@AllArgsConstructor
public enum PGTPayoutStatus {
LOSE("LOSE", 2, "输"),
WIN("WIN",1, "赢"),
DRAW("DRAW",3, "平"),
UNKNOWN("UNKNOWN",4, "未知");
private final String code;
private final Integer systemCode;
private final String description;
public static PGTPayoutStatus getByCode(String code) {
for (PGTPayoutStatus status : PGTPayoutStatus.values()) {
if (status.getCode().equals(code)) {
return status;
}
}
return UNKNOWN;
}
}

View File

@ -1,25 +0,0 @@
package com.ff.base.enums;
import com.alibaba.druid.filter.AutoLoad;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@AllArgsConstructor
@Getter
public enum TimeOutType {
GAME_EXCHANGE_MONEY("gameExchangeMoney", "游戏余额转移");
/**
*
*/
private final String code;
/**
*
*/
private final String info;
}

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, "从平台商转移额度到游戏商");
;
private final Integer code; private final Integer code;
private final String info; private final String info;

View File

@ -1,21 +0,0 @@
package com.ff.base.enums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Getter
@AllArgsConstructor
public enum TriggerType {
MANUAL(1, "用户调用手动触发"),
TIMER(2, "定时器触发");
private final int code;
private final String description;
}

View File

@ -2,12 +2,11 @@ package com.ff.base.manager;
import com.ff.base.utils.Threads; import com.ff.base.utils.Threads;
import com.ff.base.utils.spring.SpringUtils; import com.ff.base.utils.spring.SpringUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.*; import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/** /**
* *
@ -25,33 +24,10 @@ public class AsyncManager {
*/ */
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService"); private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
/**
* 线
*/
private List<ExecutorService> orderedExecutor = new ArrayList<>();
/**
* 线
*/
public static final int MAX_THREAD_COUNT = 16;
/**
* 线
*/
private ThreadPoolTaskExecutor taskExecutor;
/** /**
* *
*/ */
private AsyncManager() { private AsyncManager() {
for (int i = 0; i < MAX_THREAD_COUNT; i++) {
orderedExecutor.add(Executors.newSingleThreadExecutor());
}
executor = SpringUtils.getBean("scheduledExecutorService");
taskExecutor = SpringUtils.getBean("threadPoolTaskExecutor");
} }
private static AsyncManager me = new AsyncManager(); private static AsyncManager me = new AsyncManager();
@ -60,22 +36,6 @@ public class AsyncManager {
return me; return me;
} }
public void executeOrdered(String key, Runnable task) {
if (null == key || key.isEmpty()) {
taskExecutor.execute(task);
return;
}
int hash = key.hashCode();
int index = Math.abs(hash % MAX_THREAD_COUNT);
orderedExecutor.get(index).execute(task);
}
/** /**
* *
* *

View File

@ -38,11 +38,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
public static String DAY_END_TIME = "23:59:59"; public static String DAY_END_TIME = "23:59:59";
public static final String ISO_8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; public static final String ISO_8601_FORMAT= "yyyy-MM-dd'T'HH:mm:ss";
public static final String ISO_8601_FORMAT_Z = "yyyy-MM-dd'T'HH:mm:ss'Z'";
/** /**
* Date * Date
@ -250,6 +246,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
} }
/** /**
* LocalDate ==> Date * LocalDate ==> Date
*/ */
@ -941,38 +938,4 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
public static boolean isBetween(Long value, Long minValue, Long maxValue) { public static boolean isBetween(Long value, Long minValue, Long maxValue) {
return value >= minValue && value <= maxValue; return value >= minValue && value <= maxValue;
} }
/**
*
*
* @param dateString "yyyy-MM-dd'T'HH:mm:ss.SSS"
* @param timezone UTCAsia/Shanghai
* @return
* @throws Exception
*/
public static long convertToMillisWithTimezone(String dateString, String timezone) {
try {
// 设置日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
// 设置解析时使用的时区
sdf.setTimeZone(TimeZone.getTimeZone(timezone));
// 解析日期字符串为 Date 对象
Date date = sdf.parse(dateString);
// 获取项目默认时区
TimeZone defaultTimeZone = TimeZone.getDefault();
// 使用默认时区的 Calendar 计算
Calendar calendar = Calendar.getInstance(defaultTimeZone);
calendar.setTime(date);
// 返回该时区对应的毫秒时间戳
return calendar.getTimeInMillis();
} catch (Exception e) {
return 0;
}
}
} }

View File

@ -9,6 +9,7 @@ import java.util.concurrent.ThreadLocalRandom;
public class NumberUtils { public class NumberUtils {
/** /**
* *
* *
@ -67,13 +68,17 @@ public class NumberUtils {
Random random = new Random(); Random random = new Random();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
// 每位字符可以是大写字母A-Z或数字0-9 // 每位字符可以是字母A-Z, a-z或数字0-9
for (int i = 0; i < size; i++) { for (int i = 0; i <size ; i++) {
int choice = random.nextInt(2); int choice = random.nextInt(3);
if (choice == 0) { if (choice == 0) {
// 随机大写字母 // 随机字母(大写或小写)
char letter = (char) ('A' + random.nextInt(26)); char letter = (char) ('A' + random.nextInt(26));
sb.append(letter); sb.append(letter);
} else if (choice == 1) {
// 随机小写字母
char letter = (char) ('a' + random.nextInt(26));
sb.append(letter);
} else { } else {
// 随机数字 // 随机数字
sb.append(random.nextInt(10)); sb.append(random.nextInt(10));
@ -83,5 +88,4 @@ public class NumberUtils {
return sb.toString(); return sb.toString();
} }
} }

View File

@ -585,12 +585,12 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
/** /**
* *
* *
* @param code * @param account
* @param suffix * @param suffix
* @return {@link String } * @return {@link String }
*/ */
public static String addSuffix(String code, Object suffix) { public static String addSuffix(String account, String suffix) {
return code +"_"+ suffix; return account + suffix;
} }
/** /**

View File

@ -16,11 +16,6 @@
<dependencies> <dependencies>
<!--<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.4.10</version> &lt;!&ndash; 请检查最新版本 &ndash;&gt;
</dependency>-->
<!-- spring-boot-devtools --> <!-- spring-boot-devtools -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -1,7 +1,6 @@
package com.ff.api.controller; package com.ff.api.controller;
import cn.hutool.core.util.IdUtil;
import com.ff.annotation.CheckHeader; import com.ff.annotation.CheckHeader;
import com.ff.api.request.*; import com.ff.api.request.*;
import com.ff.api.response.*; import com.ff.api.response.*;
@ -9,9 +8,8 @@ import com.ff.base.constant.Constants;
import com.ff.base.core.controller.BaseController; import com.ff.base.core.controller.BaseController;
import com.ff.base.core.domain.AjaxResult; import com.ff.base.core.domain.AjaxResult;
import com.ff.base.core.page.TableDataInfo; import com.ff.base.core.page.TableDataInfo;
import com.ff.base.enums.*; import com.ff.base.enums.ErrorCode;
import com.ff.base.exception.base.ApiException; import com.ff.base.exception.base.ApiException;
import com.ff.base.manager.AsyncManager;
import com.ff.base.system.domain.TenantSecretKey; import com.ff.base.system.domain.TenantSecretKey;
import com.ff.base.utils.StringUtils; import com.ff.base.utils.StringUtils;
import com.ff.base.utils.bean.BeanUtils; import com.ff.base.utils.bean.BeanUtils;
@ -20,8 +18,6 @@ import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantGameQuotaService; import com.ff.common.service.ITenantGameQuotaService;
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.exchange.StepProcessorFactory;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
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;
@ -33,10 +29,8 @@ import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -44,14 +38,12 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture;
/** /**
* api * api
@ -83,6 +75,9 @@ public class ApiGameController extends BaseController {
@Resource @Resource
private ITenantGameQuotaService tenantGameQuotaService; private ITenantGameQuotaService tenantGameQuotaService;
@Resource
private ITenantGameQuotaFlowService tenantGameQuotaFlowService;
@Resource @Resource
private IGameBettingDetailsService gameBettingDetailsService; private IGameBettingDetailsService gameBettingDetailsService;
@ -98,10 +93,6 @@ public class ApiGameController extends BaseController {
@Resource @Resource
private IPlatformService platformService; private IPlatformService platformService;
@Resource
private StepProcessorFactory stepProcessorFactory;
/** /**
* *
* *
@ -115,10 +106,15 @@ public class ApiGameController extends BaseController {
if (null == platform) { if (null == platform) {
continue; continue;
} }
// List<GameSecretKeyCurrencyDTO> gameSecretKeyCurrencies =
// gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTOList(
// GameSecretKeyCurrencyDTO.builder().platformCode(gameResponse.getPlatformCode())
// .build()
// );
// List<String> currencyCode = gameSecretKeyCurrencies.stream().map(GameSecretKeyCurrencyDTO::getSystemCurrency).collect(Collectors.toList());
List<String> currencyCode = new ArrayList<>(platform.getCurrencyInfo().keySet()); List<String> currencyCode = new ArrayList<>(platform.getCurrencyInfo().keySet());
gameResponse.setCurrencyCode(currencyCode); gameResponse.setCurrencyCode(currencyCode);
} }
return AjaxResult.success(gameResponses); return AjaxResult.success(gameResponses);
} }
@ -133,7 +129,7 @@ public class ApiGameController extends BaseController {
@PostMapping("/login") @PostMapping("/login")
public AjaxResult login(@Validated @RequestBody GameLoginRequest loginRequest) { public AjaxResult login(@Validated @RequestBody GameLoginRequest loginRequest) {
Game game = gameService.selectGameByGameId(loginRequest.getGameId()); Game game = gameService.selectGameById(loginRequest.getGameId());
ApiException.notNull(game, ErrorCode.GAME_NOT_EXIST.getCode()); ApiException.notNull(game, ErrorCode.GAME_NOT_EXIST.getCode());
Platform platform = platformService.get(game.getPlatformCode()); Platform platform = platformService.get(game.getPlatformCode());
@ -158,6 +154,18 @@ public class ApiGameController extends BaseController {
String targetLang = platform.getLangInfo().get(loginRequest.getLangCode()); String targetLang = platform.getLangInfo().get(loginRequest.getLangCode());
ApiException.notNull(targetLang, ErrorCode.LANG_NOT_EXIST.getCode()); ApiException.notNull(targetLang, ErrorCode.LANG_NOT_EXIST.getCode());
// TenantSecretKey tenantSecretKey = keyConfig.get();
// GameSecretKeyCurrencyDTO secretKeyCurrencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(gamePlatform.getPlatformCode())
// .systemCurrency(memberCreateApiRequest.getCurrencyCode()).build());
// ApiException.notNull(secretKeyCurrencyDTO, ErrorCode.CURRENCY_NOT_EXIST.getCode());
// GameSecretKeyLangDTO gameSecretKeyLangDTO = gameSecretKeyLangService.findGameSecretKeyLangDTO(GameSecretKeyLangDTO.builder()
// .platformCode(gamePlatform.getPlatformCode())
// .systemLangCode(memberCreateApiRequest.getLangCode())
// .build());
// ApiException.notNull(gameSecretKeyLangDTO, ErrorCode.LANG_NOT_EXIST.getCode());
Member member = memberService.selectMemberByAccount(loginRequest.getAccount(), loginRequest.getCurrencyCode(), platform.getPlatformCode()); Member member = memberService.selectMemberByAccount(loginRequest.getAccount(), loginRequest.getCurrencyCode(), platform.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode()); ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
@ -193,13 +201,19 @@ public class ApiGameController extends BaseController {
* @return {@link AjaxResult } * @return {@link AjaxResult }
*/ */
@PostMapping("/exchange/balance") @PostMapping("/exchange/balance")
public DeferredResult<AjaxResult> exchangeBalance(@Validated @RequestBody GameExchangeBalanceRequest gameExchangeBalanceRequest) { @Transactional
public AjaxResult exchangeBalance(@Validated @RequestBody GameExchangeBalanceRequest gameExchangeBalanceRequest) {
IGamesService iGamesService = gamesService.get(gameExchangeBalanceRequest.getPlatformCode() + Constants.SERVICE); IGamesService iGamesService = gamesService.get(gameExchangeBalanceRequest.getPlatformCode() + Constants.SERVICE);
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
TenantSecretKey tenantSecretKey = keyConfig.get(); TenantSecretKey tenantSecretKey = keyConfig.get();
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(gameExchangeBalanceRequest.getPlatformCode())
// .systemCurrency(gameExchangeBalanceRequest.getCurrencyCode()).build());
//
// ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
Platform platform = platformService.get(gameExchangeBalanceRequest.getPlatformCode()); Platform platform = platformService.get(gameExchangeBalanceRequest.getPlatformCode());
ApiException.notNull(platform, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(platform, ErrorCode.PLATFORM_NOT_EXIST.getCode());
@ -218,76 +232,47 @@ public class ApiGameController extends BaseController {
} }
ApiException.notNull(keyInfo, ErrorCode.CURRENCY_NOT_EXIST.getCode()); ApiException.notNull(keyInfo, ErrorCode.CURRENCY_NOT_EXIST.getCode());
BigDecimal quota = tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder()
.platformCode(gameExchangeBalanceRequest.getPlatformCode())
.sourceId(gameExchangeBalanceRequest.getOrderId())
.currencyCode(gameExchangeBalanceRequest.getCurrencyCode())
.currency(targetCurrency)
.transferType(gameExchangeBalanceRequest.getTransferType())
.amount(gameExchangeBalanceRequest.getAmount())
.account(gameExchangeBalanceRequest.getAccount())
.tenantKey(tenantSecretKey.getTenantKey())
.systemCurrency(gameExchangeBalanceRequest.getCurrencyCode())
.agentId(keyInfo.getCode())
.agentKey(keyInfo.getKey())
.build());
// 获取用户信息 // 获取用户信息
Member member = memberService.selectMemberByAccount(gameExchangeBalanceRequest.getAccount(), gameExchangeBalanceRequest.getCurrencyCode(), gameExchangeBalanceRequest.getPlatformCode()); Member member = memberService.selectMemberByAccount(gameExchangeBalanceRequest.getAccount(), gameExchangeBalanceRequest.getCurrencyCode(), gameExchangeBalanceRequest.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode()); ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder() //操作第三方额度接口
.tenantKey(tenantSecretKey.getTenantKey()) ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO = ExchangeTransferMoneyRequestDTO.builder()
.agentId(keyInfo.getCode())
.agentKey(keyInfo.getKey())
.orderId(gameExchangeBalanceRequest.getOrderId()) .orderId(gameExchangeBalanceRequest.getOrderId())
.build() .account(member.getGameAccount())
); .currency(/*gameSecretKey.getCurrency()*/targetCurrency)
ApiException.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), ErrorCode.DUPLICATE_ORDER_ID.getCode());
Long gameExchangeMoneyId = IdUtil.getSnowflakeNextId();
GameExchangeDTO exchangeMoney = GameExchangeDTO.builder()
.id(gameExchangeMoneyId)
.tenantKey(tenantSecretKey.getTenantKey()) .tenantKey(tenantSecretKey.getTenantKey())
.memberId(member.getId()) .quota(quota)
.gameAccount(member.getGameAccount()) .amount(gameExchangeBalanceRequest.getAmount())
.memberAccount(member.getMemberAccount()) .transferType(gameExchangeBalanceRequest.getTransferType())
.exchangeType(gameExchangeBalanceRequest.getTransferType()) .vendor(platform)
.currencyCode(gameExchangeBalanceRequest.getCurrencyCode()) .keyInfo(keyInfo)
.orderId(gameExchangeBalanceRequest.getOrderId()) .systemCurrency(gameExchangeBalanceRequest.getCurrencyCode())
.balance(gameExchangeBalanceRequest.getAmount())
.triggerType(TriggerType.MANUAL.getCode())
.platformCode(gameExchangeBalanceRequest.getPlatformCode()).build();
.build();
//转出设置转出金额为0 Long exchangeTransferId = iGamesService.exchangeTransferByAgentId(exchangeTransferMoneyRequestDTO);
if (TransferType.ALL.getCode().equals(gameExchangeBalanceRequest.getTransferType())){ GameExchangeMoney gameExchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferId);
exchangeMoney.setBalance(BigDecimal.ZERO);
}
ExtInfo extInfo = platform.getExtInfo();
Long timeout = 5000L;
if (extInfo != null) {
timeout = extInfo.getTimeout(TimeOutType.GAME_EXCHANGE_MONEY.getCode());
}
DeferredResult<AjaxResult> output = new DeferredResult<>(timeout);
AsyncManager.me().executeOrdered(
exchangeMoney.getOrderId(),
() -> {
try {
stepProcessorFactory.getStepProcessor(GameExchangeStep.CREATE_ORDER).process(exchangeMoney);
GameExchangeMoney gameExchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(gameExchangeMoneyId);
GameExchangeBalanceResponse gameExchangeBalanceResponse = new GameExchangeBalanceResponse(); GameExchangeBalanceResponse gameExchangeBalanceResponse = new GameExchangeBalanceResponse();
BeanUtils.copyProperties(gameExchangeMoney, gameExchangeBalanceResponse); BeanUtils.copyProperties(gameExchangeMoney, gameExchangeBalanceResponse);
output.setResult(AjaxResult.success(gameExchangeBalanceResponse)); return AjaxResult.success(gameExchangeBalanceResponse);
} catch (Exception e) {
log.error("ApiGameController [exchangeBalance] 余额转移失败 gameExchangeMoneyId {}", gameExchangeMoneyId,e);
stepProcessorFactory.getStepProcessor(GameExchangeStep.getByCode(exchangeMoney.getStep())).rollBack(exchangeMoney);
output.setErrorResult(AjaxResult.error(ErrorCode.BALANCE_TRANSFER_FAILED.getCode(), ErrorCode.BALANCE_TRANSFER_FAILED.getMessage()));
}
}
);
// 超时时间处理逻辑
output.onTimeout(() -> {
GameExchangeMoney gameExchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(gameExchangeMoneyId);
GameExchangeBalanceResponse gameExchangeBalanceResponse = new GameExchangeBalanceResponse();
BeanUtils.copyProperties(gameExchangeMoney, gameExchangeBalanceResponse);
output.setErrorResult(AjaxResult.success(gameExchangeBalanceResponse));
});
return output;
} }
@ -327,6 +312,11 @@ public class ApiGameController extends BaseController {
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
// TenantSecretKey tenantSecretKey = keyConfig.get();
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(gameCreateFreeSpinRequest.getPlatformCode())
// .systemCurrency(gameCreateFreeSpinRequest.getCurrencyCode()).build());
// ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
Platform platform = platformService.get(gameCreateFreeSpinRequest.getPlatformCode()); Platform platform = platformService.get(gameCreateFreeSpinRequest.getPlatformCode());
ApiException.notNull(platform, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(platform, ErrorCode.PLATFORM_NOT_EXIST.getCode());

View File

@ -108,8 +108,13 @@ public class ApiMemberController extends BaseController {
} }
} }
ApiException.notNull(keyInfo, ErrorCode.CURRENCY_NOT_EXIST.getCode()); ApiException.notNull(keyInfo, ErrorCode.CURRENCY_NOT_EXIST.getCode());
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(memberCreateApiRequest.getPlatformCode())
// .systemCurrency(memberCreateApiRequest.getCurrencyCode()).build());
String gameAccount =memberService.getMemberGameAccount(memberCreateApiRequest.getPlatformCode(), tenantSecretKey.getTenantSn()); // ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
String gameAccount = StringUtils.addSuffix(memberService.getMemberGameAccount(memberCreateApiRequest.getPlatformCode()), tenantSecretKey.getTenantSn());
// 获取用户信息 // 获取用户信息
@ -144,10 +149,6 @@ public class ApiMemberController extends BaseController {
.build(); .build();
Boolean result = iGamesService.createMember(gamesBaseRequestDTO); Boolean result = iGamesService.createMember(gamesBaseRequestDTO);
Assert.isTrue(result, "建立游戏账号失败"); Assert.isTrue(result, "建立游戏账号失败");
return toAjax(Boolean.TRUE); return toAjax(Boolean.TRUE);
} }
@ -165,6 +166,12 @@ public class ApiMemberController extends BaseController {
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
TenantSecretKey tenantSecretKey = keyConfig.get();
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(memberInfoApiRequest.getPlatformCode())
// .systemCurrency(memberInfoApiRequest.getCurrencyCode()).build());
//
// ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
Platform platform = platformService.get(request.getPlatformCode()); Platform platform = platformService.get(request.getPlatformCode());
ApiException.notNull(platform, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(platform, ErrorCode.PLATFORM_NOT_EXIST.getCode());

View File

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

View File

@ -1,6 +1,5 @@
package com.ff.api.response; package com.ff.api.response;
import com.ff.game.domain.NameInfo;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -28,7 +27,7 @@ public class GameResponse implements Serializable {
/** /**
* id * id
*/ */
private String id; private Long id;
/** /**
* *
@ -61,8 +60,5 @@ public class GameResponse implements Serializable {
* *
*/ */
private List<String> currencyCode; private List<String> currencyCode;
/**
*
*/
private List<NameInfo> nameInfo;
} }

View File

@ -47,12 +47,6 @@ public class GameBalanceExchange extends GamesBaseRequestDTO implements Serializ
*/ */
private BigDecimal amount; private BigDecimal amount;
/**
*
*/
private BigDecimal amountActual;
/** /**
* *
*/ */
@ -67,9 +61,4 @@ public class GameBalanceExchange extends GamesBaseRequestDTO implements Serializ
*/ */
private String sourceId; private String sourceId;
/**
*
*/
private Boolean isAll;
} }

View File

@ -152,7 +152,7 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
BigDecimal balance = balanceChangesDTO.getBalance(); BigDecimal balance = balanceChangesDTO.getBalance();
//如果有汇率 则需要计算真实扣除额度 //如果有汇率 则需要计算真实扣除额度
if (!ObjectUtils.isEmpty(balanceChangesDTO.getActualBalance())) { if (!ObjectUtils.isEmpty(balanceChangesDTO.getActualBalance())) {
balance = NumberUtil.div(balance, balanceChangesDTO.getActualBalance(), 5, RoundingMode.FLOOR); balance = NumberUtil.div(balance, balanceChangesDTO.getActualBalance(), 2, RoundingMode.FLOOR);
} }
if (BigDecimal.ZERO.compareTo(balance) >= 0) { if (BigDecimal.ZERO.compareTo(balance) >= 0) {
@ -222,7 +222,7 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
BigDecimal balance = balanceRealChangesDTO.getBalance(); BigDecimal balance = balanceRealChangesDTO.getBalance();
//如果有汇率 则需要计算真实扣除额度 //如果有汇率 则需要计算真实扣除额度
if (!ObjectUtils.isEmpty(balanceRealChangesDTO.getActualBalance())) { if (!ObjectUtils.isEmpty(balanceRealChangesDTO.getActualBalance())) {
balance = NumberUtil.div(balance, balanceRealChangesDTO.getActualBalance(), 5, RoundingMode.FLOOR); balance = NumberUtil.div(balance, balanceRealChangesDTO.getActualBalance(), 2, RoundingMode.FLOOR);
} }
if (BigDecimal.ZERO.compareTo(balance) >= 0) { if (BigDecimal.ZERO.compareTo(balance) >= 0) {
@ -271,6 +271,13 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
*/ */
@Override @Override
public BigDecimal gameBalanceExchange(GameBalanceExchange gameBalanceExchange) { public BigDecimal gameBalanceExchange(GameBalanceExchange gameBalanceExchange) {
// 获取平台接口密钥
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(gameBalanceExchange.getPlatformCode())
// .systemCurrency(gameBalanceExchange.getCurrencyCode()).build());
// 检查平台密钥是否存在,否则抛出异常
// ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
TenantQuotaExchange tenantQuotaExchange = tenantQuotaExchangeService.getTenantQuotaExchange(Constants.USDT, gameBalanceExchange.getCurrencyCode()); TenantQuotaExchange tenantQuotaExchange = tenantQuotaExchangeService.getTenantQuotaExchange(Constants.USDT, gameBalanceExchange.getCurrencyCode());
ApiException.notNull(tenantQuotaExchange, ErrorCode.CURRENCY_EXCHANGE.getCode()); ApiException.notNull(tenantQuotaExchange, ErrorCode.CURRENCY_EXCHANGE.getCode());
@ -289,11 +296,14 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
ApiException.notNull(tenantPlatform, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(tenantPlatform, ErrorCode.PLATFORM_NOT_EXIST.getCode());
// 获取用户信息 // 获取用户信息
Member member = memberService.selectMemberByAccount(gameBalanceExchange.getAccount(), gameBalanceExchange.getCurrencyCode(), gameBalanceExchange.getPlatformCode()); Member member = memberService.selectMemberByAccount(gameBalanceExchange.getAccount(), gameBalanceExchange.getCurrencyCode(), gameBalanceExchange.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode()); ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
// 检查用户是否存在,否则抛出异常 // 检查用户是否存在,否则抛出异常
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode()); ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
@ -314,7 +324,6 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
// 如果是出账操作 // 如果是出账操作
if (isOut) { if (isOut) {
if (ObjectUtils.isEmpty(gameBalanceExchange.getIsAll())||gameBalanceExchange.getIsAll()){
// 获取第三方钱包余额 // 获取第三方钱包余额
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount()) .accounts(member.getGameAccount())
@ -323,12 +332,6 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
.agentKey(gameBalanceExchange.getAgentKey()) .agentKey(gameBalanceExchange.getAgentKey())
.build(); .build();
balanceRequestAmount = iGamesService.getMemberInfo(gamesBaseRequestDTO).getBalance(); balanceRequestAmount = iGamesService.getMemberInfo(gamesBaseRequestDTO).getBalance();
if (balanceRequestAmount.compareTo(BigDecimal.ZERO) <= 0) {
throw new ApiException(ErrorCode.INSUFFICIENT_PLAYER_BALANCE.getCode());
}
}
balanceRequestAmount = NumberUtil.add(balanceRequestAmount, NumberUtil.mul(balanceRequestAmount, NumberUtil.div(tenantPlatform.getUseCost(), Constants.HUNDRED))); balanceRequestAmount = NumberUtil.add(balanceRequestAmount, NumberUtil.mul(balanceRequestAmount, NumberUtil.div(tenantPlatform.getUseCost(), Constants.HUNDRED)));
// 计算累计转入和转出金额 // 计算累计转入和转出金额
@ -394,6 +397,8 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
if (falseTenantQuota.getBalance().compareTo(BigDecimal.ZERO) > 0) { if (falseTenantQuota.getBalance().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal falseQuotaBalance = falseTenantQuota.getBalance(); BigDecimal falseQuotaBalance = falseTenantQuota.getBalance();
if (falseQuotaBalance.compareTo(balanceRequestAmount) >= 0) { if (falseQuotaBalance.compareTo(balanceRequestAmount) >= 0) {
// 假额度足够扣除本次所需金额 // 假额度足够扣除本次所需金额

View File

@ -1,65 +0,0 @@
package com.ff.delay;
import com.ff.base.manager.AsyncManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author cengy
*/
@Service
@Slf4j
public class DelayService {
private DelayQueue<DelayTask> delayQueue = new DelayQueue<>();
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public void addTask(DelayTask delayTask) {
delayQueue.put(delayTask);
}
// 启动延迟队列任务处理
@PostConstruct
public void startProcessing() {
// 每 1 秒钟执行一次任务检查
scheduler.scheduleAtFixedRate(this::processTasks, 10, 1, TimeUnit.SECONDS);
}
// 处理过期任务
private void processTasks() {
DelayTask task = null; // 阻塞,直到队列中有任务到期
try {
task = delayQueue.take();
} catch (InterruptedException e) {
log.error("获取过期任务失败", e);
}
if (null == task) {
return;
}
AsyncManager.me().execute(new DelayRunnable(task));
}
public static class DelayRunnable implements Runnable {
DelayTask delayTask;
public DelayRunnable(DelayTask delayTask) {
this.delayTask = delayTask;
}
@Override
public void run() {
try {
delayTask.execute();
} catch (Exception e) {
log.error("处理过期任务出错", e);
}
}
}
}

View File

@ -1,44 +0,0 @@
package com.ff.delay;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* @author cengy
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class DelayTask implements Delayed {
private long delayTime;
private long expireTime;
public DelayTask(long delayTime) {
this.delayTime = delayTime;
this.expireTime = System.currentTimeMillis() + delayTime; // 设置过期时间
}
@Override
public long getDelay(TimeUnit unit) {
long diff = expireTime - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
if (this.expireTime < ((DelayTask) o).expireTime) {
return -1;
}
if (this.expireTime > ((DelayTask) o).expireTime) {
return 1;
}
return 0;
}
abstract public void execute();
}

View File

@ -52,14 +52,6 @@ public interface IGamesService {
*/ */
String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO); String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO);
/**
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO);
/** /**
* id * id
@ -74,9 +66,9 @@ public interface IGamesService {
* *
* *
* @param exchangeTransferMoneyRequestDTO dto * @param exchangeTransferMoneyRequestDTO dto
* @return {@link ExchangeTransferStatusResponseDTO } * @return {@link Boolean }
*/ */
ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO); Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO);
/** /**

View File

@ -3,8 +3,6 @@ package com.ff.game.api.ae.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
/** /**
* aeexchange * aeexchange
@ -34,13 +32,13 @@ public class AEExchangeTransferStatusResponse {
* *
*/ */
@JsonProperty("balance") @JsonProperty("balance")
private BigDecimal balance; private double balance;
/** /**
* *
*/ */
@JsonProperty("transferAmount") @JsonProperty("transferAmount")
private BigDecimal transferAmount; private double transferAmount;
/** /**
* DEPOSIT WITHDRAW * DEPOSIT WITHDRAW

View File

@ -16,13 +16,10 @@ import com.ff.base.utils.uuid.IdUtils;
import com.ff.common.dto.GameBalanceExchange; import com.ff.common.dto.GameBalanceExchange;
import com.ff.common.service.ITenantGameQuotaService; import com.ff.common.service.ITenantGameQuotaService;
import com.ff.config.KeyConfig; import com.ff.config.KeyConfig;
import com.ff.delay.DelayService;
import com.ff.delay.DelayTask;
import com.ff.game.api.IGamesService; import com.ff.game.api.IGamesService;
import com.ff.game.api.ae.client.AEClient; import com.ff.game.api.ae.client.AEClient;
import com.ff.game.api.ae.dto.*; import com.ff.game.api.ae.dto.*;
import com.ff.game.api.request.*; import com.ff.game.api.request.*;
import com.ff.game.api.sv388.impl.SV388GamesServiceImpl;
import com.ff.game.api.xk.dto.XKKickMemberDTO; import com.ff.game.api.xk.dto.XKKickMemberDTO;
import com.ff.game.domain.*; import com.ff.game.domain.*;
import com.ff.game.service.IGameBettingDetailsService; import com.ff.game.service.IGameBettingDetailsService;
@ -82,14 +79,20 @@ public class GamesAEServiceImpl implements IGamesService {
@Resource @Resource
private IGameBettingDetailsService gameBettingDetailsService; private IGameBettingDetailsService gameBettingDetailsService;
@Resource
private DelayService delayService;
/** /**
* id * id
*/ */
private static final Long GAME_ID = 1904452832756013817L; private static final Long GAME_ID = 1904452832756013817L;
/**
* ID
*/
private static final Long PLATFORM_ID = 1904411420257108325L;
/**
* id
*/
private static final Long GAME_NAME_ID = 1904452833756002317L;
/** /**
* *
@ -199,6 +202,18 @@ public class GamesAEServiceImpl implements IGamesService {
@Transactional @Transactional
@Override @Override
public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) { public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) {
// GamePlatform gamePlatform = gamePlatformService.selectGamePlatformById(PLATFORM_ID);
//没有此平台就新增一个平台
// if (ObjectUtils.isEmpty(gamePlatform)) {
// gamePlatform = new GamePlatform();
// gamePlatform.setId(PLATFORM_ID);
// gamePlatform.setPlatformCode(GamePlatforms.AE.getInfo());
// gamePlatform.setPlatformType(PlatformType.GAME_HALL.getCode());
// gamePlatform.setPlatformName(GamePlatforms.AE.getInfo() + PlatformType.GAME_HALL.getName());
// gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1);
// gamePlatform.setCreateBy(Constants.SYSTEM);
// gamePlatformService.insertGamePlatform(gamePlatform);
// }
Platform platform = gamesBaseRequestDTO.getVendor(); Platform platform = gamesBaseRequestDTO.getVendor();
Game game = gameService.selectGameById(GAME_ID); Game game = gameService.selectGameById(GAME_ID);
//不存在这个游戏 //不存在这个游戏
@ -206,6 +221,7 @@ public class GamesAEServiceImpl implements IGamesService {
game = new Game(); game = new Game();
game.setId(GAME_ID); game.setId(GAME_ID);
game.setSortNo(gameService.selectMaxSortNo(PlatformType.GAME_HALL.getCode(), GamePlatforms.AE.getCode()) + 1); game.setSortNo(gameService.selectMaxSortNo(PlatformType.GAME_HALL.getCode(), GamePlatforms.AE.getCode()) + 1);
//game.setPlatformId(gamePlatform.getId());
game.setPlatformCode(platform.getPlatformCode()); game.setPlatformCode(platform.getPlatformCode());
game.setPlatformType(PlatformType.GAME_HALL.getCode()); game.setPlatformType(PlatformType.GAME_HALL.getCode());
game.setGameCode("1"); game.setGameCode("1");
@ -216,27 +232,20 @@ public class GamesAEServiceImpl implements IGamesService {
nameInfo.setLang("zh-CN"); nameInfo.setLang("zh-CN");
nameInfo.setName("AE大厅"); nameInfo.setName("AE大厅");
game.setNameInfo(Collections.singletonList(nameInfo)); game.setNameInfo(Collections.singletonList(nameInfo));
game.setGameId(StringUtils.addSuffix(GamePlatforms.AE.getCode(), 1));
gameService.insertGame(game); gameService.insertGame(game);
}else {
NameInfo nameInfo = new NameInfo();
nameInfo.setLang("zh-CN");
nameInfo.setName("AE大厅");
game.setNameInfo(Collections.singletonList(nameInfo));
gameService.updateGame(game);
}
return CacheConstants.AE_GAMES;
} }
/*GameName gameName = gameNameService.selectGameNameById(GAME_NAME_ID);
if (ObjectUtils.isEmpty(gameName)) {
gameNameService.insertGameName(GameName.builder()
.id(GAME_NAME_ID)
.gameId(game.getId())
.gameName(game.getGameName())
.langCode("zh-CN")
.createBy(Constants.SYSTEM)
.build());
}*/
/** return CacheConstants.XK_GAMES;
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
@Override
public String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO) {
return GamePlatforms.AE.getCode() + IdUtils.simpleUUID();
} }
/** /**
@ -249,52 +258,72 @@ public class GamesAEServiceImpl implements IGamesService {
@Transactional @Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesAEServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesAEServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.AE.getInfo())
// .code(exchangeTransferMoneyRequestDTO.getAgentId())
// .build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = GamePlatforms.AE.getCode() + IdUtils.simpleUUID();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId()); //获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.AE.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
Map<String, Object> params = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, Object> params = this.getKey(exchangeTransferMoneyRequestDTO);
AETransactionResponse deposit = null; AETransactionResponse deposit = null;
try { try {
if (TransferType.GAMES.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) { if (TransferType.GAMES.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
params.put("userId", exchangeTransferMoneyRequestDTO.getAccount()); params.put("userId", exchangeTransferMoneyRequestDTO.getAccount());
params.put("txCode", exchangeTransferMoneyRequestDTO.getTransactionId()); params.put("txCode", transactionId);
params.put("transferAmount", exchangeTransferMoneyRequestDTO.getAmount()); params.put("transferAmount", exchangeTransferMoneyRequestDTO.getAmount());
deposit = AEClient.deposit(params); deposit = AEClient.deposit(params);
} else { } else {
params.put("userId", exchangeTransferMoneyRequestDTO.getAccount()); params.put("userId", exchangeTransferMoneyRequestDTO.getAccount());
params.put("txCode", exchangeTransferMoneyRequestDTO.getTransactionId()); params.put("txCode", transactionId);
params.put("withdrawType", 1); params.put("withdrawType", 1);
deposit = AEClient.withdraw(params); deposit = AEClient.withdraw(params);
} }
}finally { } finally {
BigDecimal coinBefore; BigDecimal coinBefore;
if (TransferType.GAMES.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) { if (TransferType.GAMES.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
coinBefore = NumberUtil.sub(deposit.getCurrentBalance(), deposit.getAmount()); coinBefore = NumberUtil.sub(deposit.getCurrentBalance(), deposit.getAmount());
} else { } else {
coinBefore = NumberUtil.add(deposit.getCurrentBalance(), deposit.getAmount()); coinBefore = NumberUtil.add(deposit.getCurrentBalance(), deposit.getAmount());
} }
//判断是否转移成功
if ("0000".equals(deposit.getStatus())) {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
} else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.IN_PROGRESS.getCode());
}
//更新数据 //更新数据
exchangeMoney.setBalance(deposit.getAmount()); exchangeMoney.setBalance(deposit.getAmount());
exchangeMoney.setCoinBefore(coinBefore); exchangeMoney.setCoinBefore(coinBefore);
exchangeMoney.setCoinAfter(deposit.getCurrentBalance()); exchangeMoney.setCoinAfter(deposit.getCurrentBalance());
exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore()); exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore());
exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter()); exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney); //判断是否转移成功
if ("0000".equals(deposit.getStatus())) {
exchangeMoney.setStatus(StatusType.SUCCESS.getValue());
} else {
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
}
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
} }
@ -305,10 +334,10 @@ public class GamesAEServiceImpl implements IGamesService {
* *
* *
* @param exchangeTransferMoneyRequestDTO dto * @param exchangeTransferMoneyRequestDTO dto
* @return {@link ExchangeTransferStatusResponseDTO } * @return {@link Boolean }
*/ */
@Override @Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesAEServiceImpl [exchangeTransferStatus] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesAEServiceImpl [exchangeTransferStatus] 请求参数 {}", exchangeTransferMoneyRequestDTO);
Map<String, Object> paramsMap = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, Object> paramsMap = this.getKey(exchangeTransferMoneyRequestDTO);
@ -324,38 +353,41 @@ public class GamesAEServiceImpl implements IGamesService {
status = StatusType.FAILURE.getValue(); status = StatusType.FAILURE.getValue();
} }
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeMoneyId()); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeMoneyId());
//更新
BigDecimal coinBefore; //如果失败扣除租户之前被扣额度
if (TransferType.GAMES.getCode().equals(exchangeMoney.getExchangeType())) { if (status.equals(StatusType.FAILURE.getValue())) {
coinBefore = NumberUtil.sub(exchangeTransferStatusResponse.getBalance(), exchangeTransferStatusResponse.getTransferAmount()); Member member = memberService.selectMemberById(exchangeMoney.getMemberId());
} else { tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder()
coinBefore = NumberUtil.add(exchangeTransferStatusResponse.getBalance(), exchangeTransferStatusResponse.getTransferAmount()); .platformCode(exchangeMoney.getPlatformCode())
.sourceId(exchangeMoney.getOrderId())
.currencyCode(exchangeMoney.getCurrencyCode())
.transferType(TransferType.ALL.getCode())
.amount(exchangeMoney.getBalance())
.account(member.getMemberAccount())
.tenantKey(exchangeMoney.getTenantKey())
.currency(exchangeTransferMoneyRequestDTO.getCurrency())
.systemCurrency(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.build());
}
exchangeMoney.setStatus(status);
exchangeMoney.setUpdateBy(Constants.SYSTEM);
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
return Boolean.TRUE;
} }
/**
return ExchangeTransferStatusResponseDTO.builder() *
.statusType(status) *
.balance(exchangeTransferStatusResponse.getTransferAmount()) * @param betRecordByTimeDTO dto
.coinBefore(coinBefore) * @return {@link List }<{@link GameBettingDetails }>
.coinAfter(exchangeTransferStatusResponse.getBalance()) */
.build();
}
class GetRealtimeRecordTask extends DelayTask {
BetRecordByTimeDTO betRecordByTimeDTO;
public GetRealtimeRecordTask(BetRecordByTimeDTO betRecordByTimeDTO) {
this.betRecordByTimeDTO = betRecordByTimeDTO;
}
@Override @Override
public void execute() { public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
getRealtimeRecord(betRecordByTimeDTO);
}
}
void getRealtimeRecord(BetRecordByTimeDTO betRecordByTimeDTO) {
//请求参数 //请求参数
log.info("GamesAEServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO); log.info("GamesAEServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO);
Map<String, Object> params = this.getKey(betRecordByTimeDTO); Map<String, Object> params = this.getKey(betRecordByTimeDTO);
@ -375,35 +407,27 @@ public class GamesAEServiceImpl implements IGamesService {
if (this.getIsSuccess(aeBetRecordResponse.getStatus())) { if (this.getIsSuccess(aeBetRecordResponse.getStatus())) {
//数据组装 //数据组装
this.batchInsert(aeBetRecordResponse, betRecordByTimeDTO); this.batchInsert(aeBetRecordResponse, betRecordByTimeDTO);
if (aeBetRecordResponse.getTransactions().size() >= 20000) { return Boolean.TRUE;
delayService.addTask(new GetRealtimeRecordTask(betRecordByTimeDTO));
}
//return Boolean.TRUE;
} else { } else {
redisCache.deleteObject(CacheConstants.AE_TIME_FROM);
log.error("GamesAEServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", aeBetRecordResponse.getStatus(), aeBetRecordResponse.getDesc()); log.error("GamesAEServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", aeBetRecordResponse.getStatus(), aeBetRecordResponse.getDesc());
//throw new BaseException(aeBetRecordResponse.getDesc()); throw new BaseException(aeBetRecordResponse.getDesc());
} }
} }
class GetHistoryRecordTask extends DelayTask { /**
BetRecordByTimeDTO betRecordByTimeDTO; *
*
public GetHistoryRecordTask(BetRecordByTimeDTO betRecordByTimeDTO) { * @param betRecordByTimeDTO dto
this.betRecordByTimeDTO = betRecordByTimeDTO; * @return {@link Boolean }
} */
@Override @Override
public void execute() { public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
getHistoryRecord(betRecordByTimeDTO);
}
}
void getHistoryRecord(BetRecordByTimeDTO betRecordByTimeDTO) {
log.info("GamesAEServiceImpl [getBetRecordByHistoryTime] 请求参数 {}", betRecordByTimeDTO); log.info("GamesAEServiceImpl [getBetRecordByHistoryTime] 请求参数 {}", betRecordByTimeDTO);
Map<String, Object> params = this.getKey(betRecordByTimeDTO); Map<String, Object> params = this.getKey(betRecordByTimeDTO);
String startTime = DateUtils.convertTimestampToFormattedDate(betRecordByTimeDTO.getStartTime(), DateUtils.ISO_8601_FORMAT, "GMT+8") + "+08:00";
long startTimeLong = DateUtils.addOrSubtractMinutes(betRecordByTimeDTO.getStartTime(), -40);
String startTime = DateUtils.convertTimestampToFormattedDate(startTimeLong, DateUtils.ISO_8601_FORMAT, "GMT+8") + "+08:00";
String endTime = DateUtils.convertTimestampToFormattedDate(betRecordByTimeDTO.getEndTime(), DateUtils.ISO_8601_FORMAT, "GMT+8") + "+08:00"; String endTime = DateUtils.convertTimestampToFormattedDate(betRecordByTimeDTO.getEndTime(), DateUtils.ISO_8601_FORMAT, "GMT+8") + "+08:00";
@ -416,40 +440,13 @@ public class GamesAEServiceImpl implements IGamesService {
if (this.getIsSuccess(aeBetRecordResponse.getStatus())) { if (this.getIsSuccess(aeBetRecordResponse.getStatus())) {
//数据组装 //数据组装
this.batchInsert(aeBetRecordResponse, betRecordByTimeDTO); this.batchInsert(aeBetRecordResponse, betRecordByTimeDTO);
if (aeBetRecordResponse.getTransactions().size() >= 20000) { return Boolean.TRUE;
delayService.addTask(new GetHistoryRecordTask(betRecordByTimeDTO));
}
// return Boolean.TRUE;
} else { } else {
log.error("GamesAEServiceImpl [getBetRecordByHistoryTime] 获取投注记录失败,错误代码{},错误信息{}", aeBetRecordResponse.getStatus(), aeBetRecordResponse.getDesc()); log.error("GamesAEServiceImpl [getBetRecordByHistoryTime] 获取投注记录失败,错误代码{},错误信息{}", aeBetRecordResponse.getStatus(), aeBetRecordResponse.getDesc());
// throw new BaseException(aeBetRecordResponse.getDesc()); throw new BaseException(aeBetRecordResponse.getDesc());
} }
} }
/**
*
*
* @param betRecordByTimeDTO dto
* @return {@link List }<{@link GameBettingDetails }>
*/
@Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
delayService.addTask(new GetRealtimeRecordTask(betRecordByTimeDTO));
return Boolean.TRUE;
}
/**
*
*
* @param betRecordByTimeDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
delayService.addTask(new GetHistoryRecordTask(betRecordByTimeDTO));
return Boolean.TRUE;
}
/** /**
* *
* *
@ -542,7 +539,7 @@ public class GamesAEServiceImpl implements IGamesService {
* *
* @param aeBetRecordResponse aedto * @param aeBetRecordResponse aedto
*/ */
private synchronized void batchInsert(AEBetRecordResponse aeBetRecordResponse, BetRecordByTimeDTO betRecordByTimeDTO) { private void batchInsert(AEBetRecordResponse aeBetRecordResponse, BetRecordByTimeDTO betRecordByTimeDTO) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>(); List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<String> wagersIds = new ArrayList<>(); List<String> wagersIds = new ArrayList<>();
//数据组装 //数据组装
@ -589,6 +586,10 @@ public class GamesAEServiceImpl implements IGamesService {
//转化类 //转化类
AEBetRecordResponse.Transaction resultBean = (AEBetRecordResponse.Transaction) gamesDataBuildDTO.getData(); AEBetRecordResponse.Transaction resultBean = (AEBetRecordResponse.Transaction) gamesDataBuildDTO.getData();
/*GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
.platformCode(GamePlatforms.AE.getInfo())
.currency(resultBean.getCurrency())
.build());*/
Member member = memberService.selectMemberByGameAccount(resultBean.getUserId()); Member member = memberService.selectMemberByGameAccount(resultBean.getUserId());
if (ObjectUtils.isEmpty(member)) { if (ObjectUtils.isEmpty(member)) {
@ -622,7 +623,7 @@ public class GamesAEServiceImpl implements IGamesService {
.gameCode(resultBean.getGameCode()) .gameCode(resultBean.getGameCode())
.gameType(PlatformType.GAME_HALL.getCode()) .gameType(PlatformType.GAME_HALL.getCode())
.platformCode(GamePlatforms.AE.getCode()) .platformCode(GamePlatforms.AE.getCode())
.gameId(/*GAME_ID*/ StringUtils.addSuffix(GamePlatforms.AE.getCode(), 1)) .gameId(GAME_ID)
.gameName(resultBean.getGameName()) .gameName(resultBean.getGameName())
.gameStatus(gameStatus) .gameStatus(gameStatus)
.gameStatusType(resultBean.getSettleStatus()) .gameStatusType(resultBean.getSettleStatus())

View File

@ -1,32 +0,0 @@
package com.ff.game.api.db.address;
import com.dtflys.forest.callback.AddressSource;
import com.dtflys.forest.http.ForestAddress;
import com.dtflys.forest.http.ForestRequest;
import com.ff.base.enums.GamePlatforms;
import com.ff.game.service.IPlatformService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <a href="http://api-doc-2.dbsporxxxw1box.com/#/login">DB</a>
* api
* a12345678
*
* @author cengy
*/
@Component
public class DBSportsAddress implements AddressSource {
@Resource
private IPlatformService platformService;
@Override
public ForestAddress getAddress(ForestRequest request) {
String apiBaseUrl = platformService.get(GamePlatforms.DBSports.getCode())
.getUrlInfo().getUrl();
return new ForestAddress("https", apiBaseUrl, 443, "");
}
}

View File

@ -1,110 +0,0 @@
package com.ff.game.api.db.client;
import com.dtflys.forest.annotation.*;
import com.ff.game.api.db.address.DBSportsAddress;
import com.ff.game.api.db.dto.*;
/**
* @author cengy
*/
@Address(source = DBSportsAddress.class)
public interface DBSportsClient {
/**
*
*
* @return {@link CreateUserResponse}
*/
@Post(url = "/api/user/create",
headers = {
"Content-type: application/x-www-form-urlencoded"
}
)
CreateUserResponse createMember(@Body CreateUserRequest request,
@Header("requestId") @Var("requestId") String requestId);
/**
* ()
*
* @param request
* @param requestId
* @return
*/
@Post(url = "/api/user/login",
headers = {
"Content-type: application/x-www-form-urlencoded"
}
)
LoginResponse login(@Body LoginRequest request,
@Header("requestId") String requestId);
/**
* DB0.01
*
* @param request
* @return {@link TransferResponse}
*/
@Post(url = "/api/fund/transfer",
headers = {
"Content-type: application/x-www-form-urlencoded"
}
)
TransferResponse transferIn(@Body TransferRequest request,
@Header("requestId") @Var("requestId") String requestId
);
@Post(url = "/api/fund/transfer",
headers = {
"Content-type: application/x-www-form-urlencoded"
}
)
TransferResponse transferOut(@Body TransferRequest request,
@Header("requestId") String requestId
);
@Post(url = "/api/fund/checkBalance",
headers = {
"Content-type: application/x-www-form-urlencoded"
}
)
GetMemberInfoResponse getMemberInfo(@Body GetMemberInfoRequest request,
@Header("requestId") String requestId);
/**
* ID
*/
@Post(url = "/api/fund/getTransferRecord",
headers = {
"Content-type: application/x-www-form-urlencoded"
}
)
TransferDetailResponse transferDetail(@Body TransferDetailRequest request,
@Header("requestId") String requestId);
/**
*
*
* @param request
* @param requestId
* @return
*/
@Post(value = "/api/user/kickOutUser",
headers = {
"Content-type: application/x-www-form-urlencoded"
}
)
KickUserResponse kickUser(@Body KickUserRequest request,
@Header("requestId") String requestId);
/**
* Json
*/
@Post(url = "/api/bet/queryBetListV2",
headers = {
"Content-type: application/x-www-form-urlencoded"
}
)
GetBetListResponse getBetList(@Body GetBetListRequest request,
@Header("requestId") String requestId);
}

View File

@ -1,28 +0,0 @@
package com.ff.game.api.db.dto;
import com.ff.base.utils.sign.Md5Utils;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class CreateUserRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String userName; // 用户名(可以包含但是不要等同于特殊字符或者空格长度控制在30个字符以下)
private String merchantCode; // 商户code
private String timestamp = System.currentTimeMillis() + ""; // 13位时间戳
private String currency; // 币种
private String nickname; // N 昵称
private String agentId; // N 信用网(代理id)
private String signature; // 签名 signature =MD5(MD5(userName +”&”+ merchantCode +”&”+ timestamp) + ”&”+ key)
public void buildSignature(String key) {
String signature = Md5Utils.md5New(Md5Utils.md5New(userName + "&" + merchantCode + "&" + timestamp) + "&" + key);
this.signature = signature;
}
}

View File

@ -1,26 +0,0 @@
package com.ff.game.api.db.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class CreateUserResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean status;
private String msg;
private String code;
private Long serverTime;
private UserDTO data;
@Data
public static class UserDTO {
private String userId;
}
}

View File

@ -1,9 +0,0 @@
package com.ff.game.api.db.dto;
/**
* @author cengy
*/
public class Enums {
}

View File

@ -1,93 +0,0 @@
package com.ff.game.api.db.dto;
import com.ff.base.utils.sign.Md5Utils;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class GetBetListRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private String userName;
/**
* 13
*/
private String startTime;
/**
* 13
*/
private String endTime;
/**
*
*/
private String merchantCode;
/**
* ID
*/
private Integer sportId;
/**
* ID
*/
private Long tournamentId;
/**
*
* 0:
* 1:
* 2:
* 3:
* 4:
* 5:
*/
private Integer settleStatus;
/**
* 1
*/
private Integer pageNum;
/**
* 1000
*/
private Integer pageSize;
/**
* 13
*/
private String timestamp = String.valueOf(System.currentTimeMillis());
/**
*
* 1:
* 2:
*/
private Integer orderBy;
/**
* "en"
*/
private String language;
/**
*
*/
private String signature;
public void buildSignature(String key) {
String signature = Md5Utils.md5New(Md5Utils.md5New(merchantCode + "&" + startTime + "&" + endTime + "&" + timestamp) + "&" + key);
this.signature = signature;
}
}

View File

@ -1,199 +0,0 @@
package com.ff.game.api.db.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @author cengy
*/
@Data
public class GetBetListResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean status;
private String msg;
private String code;
private Long serverTime;
private DataDTO data;
@Data
public static class DataDTO {
// 当前页码
private Integer pageNum;
// 每页条数
private Integer pageSize;
// 总条数
private Integer totalCount;
// 注单列表
private List<OrderItemDTO> list;
}
@Data
public static class OrderItemDTO {
// 用户名
private String userName;
// 商户编码
private String merchantCode;
// 订单ID
private String orderNo;
// 订单状态,具体见参数字段映射
private Integer orderStatus;
// 投注时间13位时间戳
private Long createTime;
// 订单更新时间13位时间戳
private Long modifyTime;
// 实际投注金额
private String orderAmount;
// 注单项数量
private Integer betCount;
// 结算时间13位时间戳
private Long settleTime;
// 结算金额
private Double settleAmount;
// 提前结算投注金额
private Double preBetAmount;
// 盈利金额
private Double profitAmount;
// 注单结算结果
// 2:走水3:输4:赢5:赢半6:输半7:赛事取消8:赛事延期
private Integer outcome;
// 串关类型
private Integer seriesType;
// 串关值
private String seriesValue;
// 结算次数
private Integer settleTimes;
// 设备类型1-H52-PC3-Android4-IOS
private String deviceType;
// 移动设备标识
private String deviceImei;
// 用户IP地址
private String ip;
// 币种
private String currency;
// 汇率
private BigDecimal exchangeRate;
// 最大中奖金额
private Double maxWinAmount;
// VIP等级
private Integer vipLevel;
// 投注前余额
private BigDecimal beforeTransfer;
// 投注后余额
private BigDecimal afterTransfer;
// 有效投注金额
private BigDecimal validOrderAmount;
// 注单详情列表
private List<DetailItemDTO> detailList;
}
@Data
public static class DetailItemDTO {
// 投注项编号
private Long betNo;
// 投注项ID
private Long playOptionsId;
// 赛事ID
private Long matchId;
// 比赛开始时间13位时间戳
private Long beginTime;
// 注单金额
private Double betAmount;
// 联赛名称
private String matchName;
// 比赛对阵
private String matchInfo;
// 投注类型:
// 1早盘2滚球盘3冠军盘4虚拟赛事5电竞赛事
private Integer matchType;
// 赛种ID
private Integer sportId;
// 玩法ID
private Integer playId;
// 投注项(如主客队)
private String playOptions;
// 游戏名称
private String sportName;
// 联赛ID
private Long tournamentId;
// 投注项名称
private String playOptionName;
// 玩法名称
private String playName;
// 盘口类型
private String marketType;
// 盘口值
private String marketValue;
// 让球值
private BigDecimal handicap;
// 结算比分(我方处理后所得,数据商可能未提供)
private String settleScore;
// 基准分
private String scoreBenchmark;
// 当前赔率(欧洲盘表示)
private BigDecimal oddsValue;
// 注单结算结果:
// 0:无结果2:走水3:输4:赢5:赢一半6:输一半,
// 7:赛事取消8:赛事延期11:比赛延迟12:比赛中断,
// 13:未知15:比赛放弃16:异常盘口17:未知状态,
// 18:比赛取消19:比赛延期
private String betResult;
// 最终赔率(按盘口类型)
private BigDecimal oddFinally;
}
}

View File

@ -1,36 +0,0 @@
package com.ff.game.api.db.dto;
import com.ff.base.utils.sign.Md5Utils;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class GetMemberInfoRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ,
*/
private String userName;
/**
*
*/
private String merchantCode;
/**
* Long(13)
*/
private String timestamp = System.currentTimeMillis() + "";
private String signature;
public void buildSignature(String key) {
String signature = Md5Utils.md5New(Md5Utils.md5New(merchantCode + "&" + userName + "&" + timestamp) + "&" + key);
this.signature = signature;
}
}

View File

@ -1,27 +0,0 @@
package com.ff.game.api.db.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @author cengy
*/
@Data
public class GetMemberInfoResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean status;
private String msg;
private String code;
private Long serverTime;
private MemberInfoDTO data;
@Data
public static class MemberInfoDTO {
private BigDecimal balance;
private String userName;
}
}

View File

@ -1,24 +0,0 @@
package com.ff.game.api.db.dto;
import com.ff.base.utils.sign.Md5Utils;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class KickUserRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String userName;
private String merchantCode;
private String timestamp = System.currentTimeMillis() + "";
private String signature;
public void buildSignature(String key) {
String signature = Md5Utils.md5New(Md5Utils.md5New(merchantCode + "&" + userName + "&" + timestamp) + "&" + key);
this.signature = signature;
}
}

View File

@ -1,20 +0,0 @@
package com.ff.game.api.db.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class KickUserResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean status;
private String msg;
private String code;
private Long serverTime;
}

View File

@ -1,57 +0,0 @@
package com.ff.game.api.db.dto;
import com.ff.base.utils.sign.Md5Utils;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author cengy
*/
@Data
public class LoginRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String userName;
private String merchantCode;
private String timestamp = System.currentTimeMillis() + "";
private String signature;
// 不能传错,用户可能受到设备类型相关风控措施的错误限制,进而影响正常用户货量,并产生客诉
private String terminal; // 终端类型【电脑传值pc】【移动设备传值mobile】 注这个参数传值必须是pc或者mobile
private BigDecimal balance; // 用户余额,N
private String currency; // 币种(见参数映射:支持币种 )会员首次登录,必须填写币种参数,否则注册失败
private String callbackUrl; // 玩家会话失效跳转的商户地址url(非必传)
private String stoken; // 非必传字段(商户方用户会话)
// 非必传字段(支持体育游戏其他端的跳转)
// C端⽀持跳转的游戏如果C端⽀持跳转多个游戏
// 则使⽤逗号区分。 具体字段可查看参数字段映射第6条 参数字段映射
private String jumpsupport;
private String jumpfrom; // 非必传字段,同上
private String agentId; // 信用网(代理id),N
// 用户语种:
//zh中文
//en英文
//vi越南语
//tw中文繁体
//th泰语
//ms马来语
//ad印尼语
//ko韩语
//mya:缅甸语
//pt:葡萄牙语
//es:西班牙语
//非必传字段
private String language;
private String ip; // 非必传字段 说明商户端在该字段上传入用户登陆时端ip
public void buildSignature(String key) {
String signature = Md5Utils.md5New(Md5Utils.md5New(merchantCode + "&" + userName + "&" + terminal + "&" + timestamp) + "&" + key);
this.signature = signature;
}
}

View File

@ -1,34 +0,0 @@
package com.ff.game.api.db.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author cengy
*/
@Data
public class LoginResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean status;
private String msg;
private String code;
private Long serverTime;
private LoginRespDTO data;
@Data
public static class LoginRespDTO {
private String domain; // 体育游戏前端URL
private String token; // 带有登录状态的token
private String apiDomain;// 赛事API的域名(若没有对接赛事API为空)
private String imgDomain; // 静态资源域名
private String loginUrl; // 登录体育URL可直接跳转
private String userId; // 用户id
private String url; // 参加活动的商户使用,客户端域名和参数拼接后提供商户使用
private List<String> loginUrlArr; // loginUrl数组多个域名调试使用
}
}

View File

@ -1,38 +0,0 @@
package com.ff.game.api.db.dto;
import com.ff.base.utils.sign.Md5Utils;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class TransferDetailRequest implements Serializable {
/**
* ,N
*/
private String userName;
/**
* code
*/
private String merchantCode;
/**
* id(19)
*/
private String transferId;
private String timestamp = System.currentTimeMillis() + "";
/**
*
*/
private String signature;
public void buildSignature(String key) {
String signature = Md5Utils.md5New(Md5Utils.md5New(merchantCode + "&" + transferId + "&" + timestamp) + "&" + key);
this.signature = signature;
}
}

View File

@ -1,39 +0,0 @@
package com.ff.game.api.db.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author cengy
*/
@Data
public class TransferDetailResponse implements Serializable {
private static final long serialVersionUID = 1L;
private TransferDetailDTO data;
private Boolean status;
private String msg;
private String code;
private Long serverTime;
@Data
public static class TransferDetailDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String transferId; // 交易id
private String merchantCode; // 商户代码
private Long userId; // 用户id
private Integer transferType; // 交易类型 1加款2扣款
private BigDecimal amount; // 交易金额
private BigDecimal beforeTransfer; // 转账前余额
private Integer afterTransfer; // 转账后余额
private Integer status; // 转账成功与否(0:失败1:成功)
private String mag; // 转账模式 1免转2转账
private Integer transferMode; // 转账涉及订单(transferMode为2时该字段为空)
private Long createTime; // 交易时间
}
}

View File

@ -1,28 +0,0 @@
package com.ff.game.api.db.dto;
import com.ff.base.utils.sign.Md5Utils;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class TransferRequest implements Serializable {
private String userName;
private String merchantCode;
private int transferType; // 1加款 2扣款
private String amount; // 金额小数2位
private String transferId; // 交易的讯息号唯一标示不可重复19位长度的字符串
private String timestamp = String.valueOf(System.currentTimeMillis());
private String signature;
public void buildSignature(String key) {
String signature = Md5Utils.md5New(Md5Utils.md5New(merchantCode + "&" + userName + "&" + transferType + "&" + amount + "&" + transferId + "&" + timestamp) + "&" + key);
this.signature = signature;
}
}

View File

@ -1,25 +0,0 @@
package com.ff.game.api.db.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class TransferResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean status;
private String msg;
private String code;
private Long serverTime;
private TransferDTO data;
@Data
public static class TransferDTO {
private String userName;
}
}

View File

@ -1,609 +0,0 @@
package com.ff.game.api.db.impl;
import cn.hutool.core.util.IdUtil;
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.utils.DateUtils;
import com.ff.base.utils.StringUtils;
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.db.dto.*;
import com.ff.game.api.request.*;
import com.ff.game.domain.*;
import com.ff.game.service.IGameBettingDetailsService;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.game.service.IGameService;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import com.ff.game.api.db.client.DBSportsClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* DB
*
* @author cengy
* @date 2024/10/21
*/
@Service("DBSportsService")
@Slf4j
public class DBSportsServiceImpl implements IGamesService {
@Resource
private RedisCache redisCache;
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private IGameService gameService;
@Resource
private IMemberService memberService;
@Resource
private DBSportsClient dbSportsClient;
@Resource
private IGameBettingDetailsService gameBettingDetailsService;
/**
*
*
* @param errorCode
* @return {@link Boolean }
*/
private Boolean isSuccess(String errorCode) {
return "0000".equals(errorCode);
}
String getSign(String bodyJsonString, String merchantId, String merchantApiSecret, long requestTimestamp) {
String stringThatNeedsToBeSigned = bodyJsonString + "." + merchantId + "." + requestTimestamp + "." + merchantApiSecret;
String sign = Md5Utils.md5New(stringThatNeedsToBeSigned);
return sign;
}
/**
*
*
* @param requestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean createMember(CreateMemberRequestDTO requestDTO) {
CreateUserRequest request = new CreateUserRequest();
request.setUserName(requestDTO.getAccount());
request.setMerchantCode(requestDTO.getAgentId());
request.setCurrency(requestDTO.getCurrency());
request.buildSignature(requestDTO.getAgentKey());
//String lang = requestDTO.getLan
String requestId = IdUtils.fastUUID();
CreateUserResponse response = dbSportsClient.createMember(request, requestId);
if (isSuccess(response.getCode())) {
return Boolean.TRUE;
}
log.error("创建会员失败, errorCode:{}, errorMessage:{}", response.getCode(), response.getMsg());
throw new ApiException(ErrorCode.Create_Member_Failure.getCode());
}
/**
* id
*
* @param requestDTO
* @return {@link Long }
*/
@Override
@Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO requestDTO) {
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(requestDTO.getGameExchangeId());
// 转入
if (requestDTO.getTransferType().equals(TransferType.GAMES.getCode())) {
TransferRequest request = new TransferRequest();
request.setUserName(requestDTO.getAccount());
request.setTransferType(1);
request.setTransferId(requestDTO.getTransactionId());
request.setMerchantCode(requestDTO.getAgentId());
request.setAmount(requestDTO.getAmount().toString());
request.buildSignature(requestDTO.getAgentKey());
TransferResponse response = dbSportsClient.transferIn(
request, IdUtils.fastUUID()
);
if (isSuccess(response.getCode())) {
GetMemberInfoRequest queryMemberRequest = new GetMemberInfoRequest();
queryMemberRequest.setUserName(requestDTO.getAccount());
queryMemberRequest.setMerchantCode(requestDTO.getAgentId());
queryMemberRequest.buildSignature(requestDTO.getAgentKey());
String requestId = IdUtils.fastUUID();
try {
GetMemberInfoResponse queryMemberResponse = dbSportsClient.getMemberInfo(queryMemberRequest, requestId);
if (this.isSuccess(queryMemberResponse.getCode())) {
BigDecimal transAmount = requestDTO.getAmount();
BigDecimal afterAmount = queryMemberResponse.getData().getBalance();
BigDecimal beforeAmount = afterAmount.subtract(transAmount);
exchangeMoney.setBalance(transAmount);
exchangeMoney.setCoinBefore(beforeAmount);
exchangeMoney.setCoinAfter(afterAmount);
exchangeMoney.setCurrencyBefore(beforeAmount);
exchangeMoney.setCurrencyAfter(afterAmount);
}
} catch (Exception e) {
log.error("查询会员失败, errorCode:{}, errorMessage:{}", response.getCode(), response.getMsg(), e);
}
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
throw new ApiException(ErrorCode.Transfer_In_Failure.getCode());
}
} else {
// 获取第三方钱包余额
MemberInfoRequestDTO memberInfoRequestDTO = MemberInfoRequestDTO.builder()
.accounts(requestDTO.getAccount())
.agentId(requestDTO.getAgentId())
.agentKey(requestDTO.getAgentKey())
.build();
BigDecimal balance = this.getMemberInfo(memberInfoRequestDTO).getBalance();
if (balance.compareTo(BigDecimal.ZERO) <= 0) {
throw new ApiException(ErrorCode.INSUFFICIENT_PLAYER_BALANCE.getCode());
}
TransferRequest request = new TransferRequest();
request.setUserName(requestDTO.getAccount());
request.setTransferType(2); // 转出
request.setTransferId(requestDTO.getTransactionId());
request.setMerchantCode(requestDTO.getAgentId());
request.setAmount(/*requestDTO.getAmount().toString()*/ balance.toString());
request.buildSignature(requestDTO.getAgentKey());
TransferResponse response = dbSportsClient
.transferOut(
request, IdUtils.fastUUID()
);
//判断是否转移成功
if (this.isSuccess(response.getCode())) {
BigDecimal transAmount = balance;
BigDecimal beforeAmount = balance;
BigDecimal afterAmount = BigDecimal.ZERO;
//更新数据
exchangeMoney.setBalance(transAmount);
exchangeMoney.setCoinBefore(beforeAmount);
exchangeMoney.setCoinAfter(afterAmount);
exchangeMoney.setCurrencyBefore(beforeAmount);
exchangeMoney.setCurrencyAfter(afterAmount);
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
throw new ApiException(ErrorCode.Transfer_Out_Failure.getCode());
}
}
return exchangeMoney.getId();
}
/**
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
@Override
public String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO) {
return gameExchangeMoneyService.getTransactionId(GamePlatforms.DBSports.getInfo(), 11);
}
/**
*
*
* @param requestDTO dto
* @return {@link MemberInfoResponseDTO }
*/
@Override
public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO requestDTO) {
GetMemberInfoRequest request = new GetMemberInfoRequest();
request.setUserName(requestDTO.getAccounts());
request.setMerchantCode(requestDTO.getAgentId());
request.buildSignature(requestDTO.getAgentKey());
String requestId = IdUtils.fastUUID();
GetMemberInfoResponse response = dbSportsClient.getMemberInfo(request, requestId);
//判断是否获取成功
if (this.isSuccess(response.getCode())) {
return MemberInfoResponseDTO.builder()
.status(GameMemberStatus.UNKNOWN.getCode())
.balance(response.getData().getBalance())
.account(requestDTO.getAccounts())
.build();
}
throw new ApiException(ErrorCode.Get_Member_Info_Failure.getCode());
}
/**
*
*
* @param requestDTO
* @return {@link String }
*/
@Override
public String loginWithoutRedirect(GamesLogin requestDTO) {
LoginRequest request = new LoginRequest();
request.setUserName(requestDTO.getAccount());
request.setMerchantCode(requestDTO.getAgentId());
if (requestDTO.getPlatform().equalsIgnoreCase("web")) {
request.setTerminal("pc");
} else {
request.setTerminal("mobile");
}
request.setLanguage(requestDTO.getLang());
request.setCurrency(requestDTO.getCurrency());
request.buildSignature(requestDTO.getAgentKey());
LoginResponse response = dbSportsClient.login(
request, IdUtils.fastUUID()
);
if (this.isSuccess(response.getCode())) {
LoginResponse.LoginRespDTO respDTO = response.getData();
String loginURL = respDTO.getLoginUrl();
if (StringUtils.isEmpty(loginURL)) {
throw new ApiException(ErrorCode.Get_Url_Failure.getCode());
}
return loginURL;
}
throw new ApiException(ErrorCode.Get_Url_Failure.getCode());
}
/**
*
*
* @param gamesBaseRequestDTO dto
* @return {@link String }
*/
@Transactional
@Override
public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) {
Platform platform = gamesBaseRequestDTO.getVendor();
Game condition = new Game();
condition.setPlatformCode(platform.getPlatformCode());
condition.setPlatformType(PlatformType.SPORTS.getCode());
List<Game> gameList = gameService.selectGameList(condition);
//不存在这个游戏
if (ObjectUtils.isEmpty(gameList)) {
Game game = new Game();
game.setId(IdUtil.getSnowflakeNextId());
game.setSortNo(1);
game.setPlatformCode(platform.getPlatformCode());
game.setPlatformType(PlatformType.SPORTS.getCode());
game.setGameCode("1");
game.setGameSourceType(String.valueOf(1));
game.setGameName(GamePlatforms.DBSports.getInfo());
game.setCreateBy(Constants.SYSTEM);
NameInfo nameInfo = new NameInfo();
nameInfo.setLang("zh-CN");
nameInfo.setName("DB体育");
game.setNameInfo(Collections.singletonList(nameInfo));
gameService.insertGame(game);
}
/*GameName gameName = gameNameService.selectGameNameById(GAME_NAME_ID);
if (ObjectUtils.isEmpty(gameName)) {
gameNameService.insertGameName(GameName.builder()
.id(GAME_NAME_ID)
.gameId(game.getId())
.gameName(game.getGameName())
.langCode("zh-CN")
.createBy(Constants.SYSTEM)
.build());
}*/
return CacheConstants.DB_Sports;
}
/**
*
*
* @param requestDTO dto
* @return {@link Boolean }
*/
@Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO requestDTO) {
GameExchangeMoney gameExchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(requestDTO.getGameExchangeMoneyId());
if (null == gameExchangeMoney) {
throw new ApiException(ErrorCode.Transfer_Not_Exist.getCode());
}
Integer status = StatusType.IN_PROGRESS.getValue();
if (!Objects.equals(gameExchangeMoney.getStatus(), StatusType.SUCCESS.getValue())) {
TransferDetailRequest request = new TransferDetailRequest();
request.setMerchantCode(requestDTO.getAgentId());
request.setTransferId(gameExchangeMoney.getOrderId());
request.buildSignature(requestDTO.getAgentKey());
TransferDetailResponse response = dbSportsClient.transferDetail(
request, IdUtils.fastUUID()
);
if (this.isSuccess(response.getCode()) && response.getData().getStatus() == 1) {
status = StatusType.SUCCESS.getValue();
} else {
status = StatusType.FAILURE.getValue();
}
}
return ExchangeTransferStatusResponseDTO.builder()
.statusType(status)
.balance(gameExchangeMoney.getBalance())
.coinBefore(gameExchangeMoney.getCoinBefore())
.coinAfter(gameExchangeMoney.getCoinAfter())
.build();
}
/**
*
*
* @param requestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO requestDTO) {
this.getRealtimeRecord(requestDTO, 1);
return Boolean.TRUE;
}
void getRealtimeRecord(BetRecordByTimeDTO requestDTO, int pageNum) {
GetBetListRequest request = new GetBetListRequest();
request.setStartTime(String.valueOf(requestDTO.getStartTime()));
request.setEndTime(String.valueOf(requestDTO.getEndTime()));
request.setMerchantCode(requestDTO.getAgentId());
request.setPageNum(pageNum);
request.setPageSize(1000);
request.buildSignature(requestDTO.getAgentKey());
GetBetListResponse response = dbSportsClient.getBetList(
request, IdUtils.fastUUID()
);
if (this.isSuccess(response.getCode())) {
List<GetBetListResponse.OrderItemDTO> list = response.getData().getList();
if (CollectionUtils.isEmpty(list)) {
return;
}
this.batchInsert(list, requestDTO);
getRealtimeRecord(requestDTO, ++pageNum);
}
}
/**
*
*
* @param requestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO requestDTO) {
return Boolean.TRUE;
}
/**
*
*
* @param createFreeSpinRequest
* @return {@link Boolean }
*/
@Override
public Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest) {
throw new BaseException("暂不支持免费局数");
}
/**
*
*
* @param getGameDetailRequestDTO dto
* @return {@link GetGameDetailResponseDTO }
*/
@Override
public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param kickMemberRequestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) {
KickUserRequest request = new KickUserRequest();
request.setUserName(kickMemberRequestDTO.getAccount());
request.setMerchantCode(kickMemberRequestDTO.getAgentId());
request.buildSignature(kickMemberRequestDTO.getAgentKey());
KickUserResponse kickUserResponse = dbSportsClient.kickUser(request, IdUtils.fastUUID());
if (this.isSuccess(kickUserResponse.getCode())) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}
/**
*
*
* @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 gameDemoLoginRequestDTO dto
* @return {@link GameDemoLoginResponseDTO }
*/
@Override
public GameDemoLoginResponseDTO gameDemoLogin(GameDemoLoginRequestDTO gameDemoLoginRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param settledOrderList
*/
private void batchInsert(List<GetBetListResponse.OrderItemDTO> settledOrderList, BetRecordByTimeDTO betRecordByTimeDTO) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<String> wagersIds = new ArrayList<>();
//数据组装
List<GetBetListResponse.OrderItemDTO> dataList = settledOrderList;
if (CollectionUtils.isEmpty(dataList)) {
return;
}
//数据转化
for (GetBetListResponse.OrderItemDTO dataBean : dataList) {
if (dataBean.getOrderStatus() != 1) { // 只关心结算的
continue;
}
GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder()
.platform(betRecordByTimeDTO.getVendor())
.data(dataBean).build());
if (!ObjectUtils.isEmpty(bettingDetails)) {
bettingDetails.setId(IdUtil.getSnowflakeNextId());
gameBettingDetails.add(bettingDetails);
}
wagersIds.add(dataBean.getOrderNo());
}
if (CollectionUtils.isEmpty(gameBettingDetails)) {
return;
}
//查询重复数据id
List<String> removeWagersIds = gameBettingDetailsService
.selectGameBettingDetailsByWagersId(wagersIds, GamePlatforms.DBSports.getCode());
//用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) {
//转化类
GetBetListResponse.OrderItemDTO dataBean = (GetBetListResponse.OrderItemDTO) gamesDataBuildDTO.getData();
Member member = memberService.selectMemberByGameAccount(dataBean.getUserName());
if (ObjectUtils.isEmpty(member)) {
return null;
}
//List<Game> gameList = redisCache.getCacheList(CacheConstants.DB_Sports);
//Game game = gameList.get(0);
BigDecimal originPayoffAmount = BigDecimal.valueOf(dataBean.getSettleAmount());
BigDecimal betAmount = new BigDecimal(dataBean.getOrderAmount());
int compareResult = originPayoffAmount.compareTo(betAmount);
long payoffTime = dataBean.getSettleTime();
long createTime = dataBean.getCreateTime();
Platform platform = gamesDataBuildDTO.getPlatform();
String systemCurrency = platform.getOurCurrency(dataBean.getCurrency());
//数据构造
GameBettingDetails gameBettingDetails = GameBettingDetails.builder()
.tenantKey(member.getTenantKey())
//保存我们的币种id
.currencyCode(systemCurrency)
.memberId(member.getId())
.gameCode("1")
.gameType(PlatformType.SPORTS.getCode()) // 体育
.platformCode(GamePlatforms.DBSports.getCode())
.gameId(GamePlatforms.DBSports.getCode() + "_1")
.gameName(GamePlatforms.DBSports.getInfo())
.gameStatus(compareResult > 0 ? GameStatus.WIN.getCode() : compareResult < 0 ? GameStatus.FAIL.getCode() : GameStatus.FLAT.getCode())
.gameStatusType(1) // 一般下注
.gameCurrencyCode(dataBean.getCurrency())
.account(dataBean.getUserName())
.wagersId(dataBean.getOrderNo())
.wagersTime(createTime)
.betAmount(betAmount)
.payoffTime(payoffTime)
.payoffAmount(originPayoffAmount.abs())
.settlementTime(payoffTime)
.turnover(betAmount)
.orderNo(dataBean.getOrderNo())
.settlementStatus(SettlementStatusEnum.COMPLETED.getCode())
.build();
gameBettingDetails.setCreateBy(Constants.SYSTEM);
gameBettingDetails.setCreateTime(DateUtils.getNowDate());
return gameBettingDetails;
}
}

View File

@ -55,16 +55,6 @@ public interface DGClient {
@Post(url = "/v2/api/transfer") @Post(url = "/v2/api/transfer")
DGTransactionResponseDTO exchangeTransferByAgentId(@JSONBody Map<String, Object> params, @Header Map<String, Object> header); DGTransactionResponseDTO exchangeTransferByAgentId(@JSONBody Map<String, Object> params, @Header Map<String, Object> header);
/**
*
*
* @param params
* @param header
* @return {@link DGTransactionResponseDTO }
*/
@Post(url = "/v2/api/checkTransfer")
DGTransactionResponseDTO exchangeTransferStatus(@JSONBody Map<String, Object> params, @Header Map<String, Object> header);
/** /**
* *
* *

View File

@ -8,13 +8,11 @@ import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException; 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.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.StringUtils;
import com.ff.base.utils.sign.Md5Utils; import com.ff.base.utils.sign.Md5Utils;
import com.ff.base.utils.uuid.IdUtils; import com.ff.base.utils.uuid.IdUtils;
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.ae.dto.AEExchangeTransferStatusResponse;
import com.ff.game.api.dg.client.DGClient; import com.ff.game.api.dg.client.DGClient;
import com.ff.game.api.dg.dto.*; import com.ff.game.api.dg.dto.*;
import com.ff.game.api.request.*; import com.ff.game.api.request.*;
@ -71,6 +69,15 @@ public class GamesDGServiceImpl implements IGamesService {
*/ */
private static final Long GAME_ID = 1904452832756003817L; private static final Long GAME_ID = 1904452832756003817L;
/**
* ID
*/
private static final Long PLATFORM_ID = 1904411420157108325L;
/**
* id
*/
private static final Long GAME_NAME_ID = 1904452832756002317L;
/** /**
* *
@ -188,13 +195,25 @@ public class GamesDGServiceImpl implements IGamesService {
@Transactional @Transactional
@Override @Override
public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) { public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) {
//GamePlatform gamePlatform = gamePlatformService.selectGamePlatformById(PLATFORM_ID);
//没有此平台就新增一个平台
/*if (ObjectUtils.isEmpty(gamePlatform)) {
gamePlatform = new GamePlatform();
gamePlatform.setId(PLATFORM_ID);
gamePlatform.setPlatformCode(GamePlatforms.DG.getInfo());
gamePlatform.setPlatformType(PlatformType.CARD_GAME.getCode());
gamePlatform.setPlatformName(GamePlatforms.DG.getInfo() + PlatformType.CARD_GAME.getName());
gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1);
gamePlatform.setCreateBy(Constants.SYSTEM);
gamePlatformService.insertGamePlatform(gamePlatform);
}*/
Game game = gameService.selectGameById(GAME_ID); Game game = gameService.selectGameById(GAME_ID);
//不存在这个游戏 //不存在这个游戏
if (ObjectUtils.isEmpty(game)) { if (ObjectUtils.isEmpty(game)) {
game = new Game(); game = new Game();
game.setId(GAME_ID); game.setId(GAME_ID);
game.setSortNo(1); game.setSortNo(1);
//game.setPlatformId(gamePlatform.getId());
game.setPlatformCode(GamePlatforms.DG.getCode()); game.setPlatformCode(GamePlatforms.DG.getCode());
game.setPlatformType(PlatformType.GAME_HALL.getCode()); game.setPlatformType(PlatformType.GAME_HALL.getCode());
game.setGameCode("1"); game.setGameCode("1");
@ -202,30 +221,21 @@ public class GamesDGServiceImpl implements IGamesService {
game.setGameName("真人棋牌"); game.setGameName("真人棋牌");
game.setCreateBy(Constants.SYSTEM); game.setCreateBy(Constants.SYSTEM);
game.setNameInfo(Collections.singletonList(new NameInfo("真人棋牌", "zh-CN"))); game.setNameInfo(Collections.singletonList(new NameInfo("真人棋牌", "zh-CN")));
game.setGameId(StringUtils.addSuffix(GamePlatforms.DG.getCode(), 1));
gameService.insertGame(game); gameService.insertGame(game);
}else {
game.setNameInfo(Collections.singletonList(new NameInfo("真人棋牌", "zh-CN")));
gameService.updateGame(game);
} }
/*GameName gameName = gameNameService.selectGameNameById(GAME_NAME_ID);
if (ObjectUtils.isEmpty(gameName)) {
gameNameService.insertGameName(GameName.builder()
.id(GAME_NAME_ID)
.gameId(game.getId())
.gameName(game.getGameName())
.langCode("zh-CN")
.createBy(Constants.SYSTEM)
.build());
}*/
return CacheConstants.DG_GAMES; return CacheConstants.DG_GAMES;
} }
/**
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
@Override
public String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO) {
return GamePlatforms.DG.getInfo() + IdUtils.simpleUUID();
}
/** /**
* id * id
* *
@ -236,16 +246,41 @@ public class GamesDGServiceImpl implements IGamesService {
@Transactional @Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesDGServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesDGServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.DG.getInfo())
// .code(exchangeTransferMoneyRequestDTO.getAgentId())
// .build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = GamePlatforms.DG.getInfo() + IdUtils.simpleUUID();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId()); //获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.DG.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount(); BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount();
if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) { if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
// 获取第三方钱包余额 // 获取第三方钱包余额
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(exchangeTransferMoneyRequestDTO.getAccount()) .accounts(member.getGameAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId()) .agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()) .currency(exchangeTransferMoneyRequestDTO.getCurrency())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey()) .agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
@ -258,7 +293,7 @@ public class GamesDGServiceImpl implements IGamesService {
Map<String, Object> params = new LinkedHashMap<>(); Map<String, Object> params = new LinkedHashMap<>();
params.put("username", exchangeTransferMoneyRequestDTO.getAccount()); params.put("username", exchangeTransferMoneyRequestDTO.getAccount());
params.put("amount", amount); params.put("amount", amount);
params.put("serial", exchangeTransferMoneyRequestDTO.getTransactionId()); params.put("serial", transactionId);
Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO);
DGTransactionResponseDTO dgTransactionResponseDTO = DGClient.exchangeTransferByAgentId(params, headerMap); DGTransactionResponseDTO dgTransactionResponseDTO = DGClient.exchangeTransferByAgentId(params, headerMap);
@ -271,13 +306,9 @@ public class GamesDGServiceImpl implements IGamesService {
exchangeMoney.setCoinAfter(dgTransactionResponseDTO.getBalance()); exchangeMoney.setCoinAfter(dgTransactionResponseDTO.getBalance());
exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore()); exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore());
exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter()); exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter());
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode()); exchangeMoney.setStatus(StatusType.SUCCESS.getValue());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode()); gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else { } else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
log.error("GamesDGServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", dgTransactionResponseDTO.getCodeId(), dgTransactionResponseDTO.getMsg()); log.error("GamesDGServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", dgTransactionResponseDTO.getCodeId(), dgTransactionResponseDTO.getMsg());
throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode()); throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode());
} }
@ -289,31 +320,11 @@ public class GamesDGServiceImpl implements IGamesService {
* *
* *
* @param exchangeTransferMoneyRequestDTO dto * @param exchangeTransferMoneyRequestDTO dto
* @return {@link ExchangeTransferStatusResponseDTO } * @return {@link Boolean }
*/ */
@Override @Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesDGServiceImpl [exchangeTransferStatus] 请求参数 {}", exchangeTransferMoneyRequestDTO); return Boolean.TRUE;
Map<String, Object> params = new LinkedHashMap<>();
params.put("serial", exchangeTransferMoneyRequestDTO.getOrderId());
Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO);
DGTransactionResponseDTO dgTransactionResponseDTO = DGClient.exchangeTransferStatus(params, headerMap);
Integer status = StatusType.IN_PROGRESS.getValue();
if (this.getIsSuccess(dgTransactionResponseDTO.getCodeId())) {
status = StatusType.SUCCESS.getValue();
} else {
status = StatusType.FAILURE.getValue();
}
return ExchangeTransferStatusResponseDTO.builder()
.statusType(status)
.balance(dgTransactionResponseDTO.getAmount().abs())
.coinBefore(NumberUtil.sub(dgTransactionResponseDTO.getBalance(), dgTransactionResponseDTO.getAmount().abs()).abs())
.coinAfter(dgTransactionResponseDTO.getBalance())
.build();
} }
@ -325,7 +336,6 @@ public class GamesDGServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
SleepUtil.sleep(50000);
//请求参数 //请求参数
log.info("GamesDGServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO); log.info("GamesDGServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO);
Map<String, Object> key = this.getKey(betRecordByTimeDTO); Map<String, Object> key = this.getKey(betRecordByTimeDTO);
@ -350,7 +360,7 @@ public class GamesDGServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
return Boolean.FALSE; return null;
} }
/** /**
@ -571,8 +581,7 @@ public class GamesDGServiceImpl implements IGamesService {
.gameCode(String.valueOf(resultBean.getGameId())) .gameCode(String.valueOf(resultBean.getGameId()))
.gameType(PlatformType.CARD_GAME.getCode()) .gameType(PlatformType.CARD_GAME.getCode())
.platformCode(GamePlatforms.DG.getCode()) .platformCode(GamePlatforms.DG.getCode())
//.gameId(GAME_ID) .gameId(GAME_ID)
.gameId(game.getGameId())
.gameName(game.getGameName()) .gameName(game.getGameName())
.gameStatus(gameStatus) .gameStatus(gameStatus)
.gameStatusType(resultBean.getGameType()) .gameStatusType(resultBean.getGameType())

View File

@ -1,118 +0,0 @@
package com.ff.game.api.exchange;
import com.ff.base.enums.GameExchangeStep;
import com.ff.base.enums.GameExchangeStepStatus;
import com.ff.base.exception.base.BaseException;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.domain.GameExchangeMoney;
import com.ff.game.service.IGameExchangeMoneyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Slf4j
public abstract class AbstractStepProcessor implements StepProcessorService {
@Resource
private StepProcessorFactory stepProcessorFactory;
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
/**
*
*
* @param gameExchangeMoney
*/
@Override
public void process(GameExchangeDTO gameExchangeMoney) {
boolean processResult = false;
try {
processResult = doProcess(gameExchangeMoney);
} catch (Exception e) {
log.error("游戏余额转移{}-步骤任务{}-执行异常", gameExchangeMoney.getId(), stepKey().getDescription(), e);
throw new BaseException("游戏余额转移"+gameExchangeMoney.getId()+"-步骤任务"+stepKey().getDescription()+"-执行异常" );
}
//更新状态
if (processResult) {
log.info("游戏余额转移{}-步骤任务{}-执行成功", gameExchangeMoney.getId(), stepKey().getDescription());
triggerNextStep(gameExchangeMoney);
}
}
/**
*
*
* @param gameExchangeMoney
*/
@Override
public void rollBack(GameExchangeDTO gameExchangeMoney){
boolean processResult = false;
try {
processResult = doRollBack(gameExchangeMoney);
} catch (Exception e) {
log.error("游戏余额转移{}-步骤任务{}-回滚异常", gameExchangeMoney.getId(), stepKey().getDescription(), e);
}
if (processResult) {
log.info("游戏余额转移{}-步骤任务{}-回滚成功", gameExchangeMoney.getId(), stepKey().getDescription());
triggerBackStep(gameExchangeMoney);
}
}
/**
* 退
*
* @param exchangeMoney
*/
private void triggerBackStep(GameExchangeDTO exchangeMoney) {
GameExchangeStep nextStep = backStepProcessor();
if (nextStep != null) {
stepProcessorFactory.getStepProcessor(nextStep).rollBack(exchangeMoney);
}
}
/**
*
*
* @param exchangeMoney
*/
private void triggerNextStep(GameExchangeDTO exchangeMoney) {
GameExchangeStep nextStep = nextStepProcessor();
if (nextStep != null) {
stepProcessorFactory.getStepProcessor(nextStep).process(exchangeMoney);
}
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
* @throws Exception
*/
abstract public boolean doRollBack(GameExchangeDTO gameExchangeMoney) throws Exception;
/**
* do
*
* @param gameExchangeMoney
* @return boolean
* @throws Exception
*/
abstract public boolean doProcess(GameExchangeDTO gameExchangeMoney) throws Exception;
}

View File

@ -1,47 +0,0 @@
package com.ff.game.api.exchange;
import com.ff.base.enums.GameExchangeStep;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Component
public class StepProcessorFactory {
@Autowired
List<StepProcessorService> stepProcessors;
private Map<GameExchangeStep, StepProcessorService> processorMap;
@PostConstruct
public void init() {
Map<GameExchangeStep, StepProcessorService> map = new HashMap<>();
for (StepProcessorService stepProcessor : stepProcessors) {
map.put(stepProcessor.stepKey(), stepProcessor);
}
processorMap = Collections.unmodifiableMap(map);
}
/**
*
*
* @param stepKey
* @return {@link StepProcessorService }
*/
public StepProcessorService getStepProcessor(GameExchangeStep stepKey) {
return processorMap.get(stepKey);
}
}

View File

@ -1,56 +0,0 @@
package com.ff.game.api.exchange;
import com.ff.base.enums.GameExchangeStep;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
/**
*
*
* @author shi
* @date 2025/04/09
*/
public interface StepProcessorService {
/**
*
*
* @return {@link GameExchangeStep }
*/
GameExchangeStep stepKey();
/**
*
*
* @param gameExchangeMoney
*/
void process(GameExchangeDTO gameExchangeMoney);
/**
* 退
*
* @param gameExchangeMoney
*/
void rollBack(GameExchangeDTO gameExchangeMoney);
/**
*
*
*
* @return
*/
GameExchangeStep nextStepProcessor();
/**
*
*
*
* @return {@link GameExchangeStep }
*/
GameExchangeStep backStepProcessor();
}

View File

@ -1,32 +0,0 @@
package com.ff.game.api.exchange.dto;
import com.ff.base.annotation.Excel;
import com.ff.game.domain.GameExchangeMoney;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* dto
*
* @author shi
* @date 2025/04/09
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class GameExchangeDTO extends GameExchangeMoney {
/**
* 1 2
*/
private Integer triggerType;
/** 会员账号 */
private String memberAccount;
/** 游戏账号 */
private String gameAccount;
}

View File

@ -1,170 +0,0 @@
package com.ff.game.api.exchange.impl;
import com.ff.base.constant.Constants;
import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException;
import com.ff.base.utils.StringUtils;
import com.ff.common.domain.TenantGameQuotaFlow;
import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.dto.GameBalanceExchange;
import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantGameQuotaService;
import com.ff.game.api.IGamesService;
import com.ff.game.api.exchange.AbstractStepProcessor;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.api.request.ExchangeTransferMoneyRequestDTO;
import com.ff.game.api.request.ExchangeTransferStatusRequestDTO;
import com.ff.game.api.request.ExchangeTransferStatusResponseDTO;
import com.ff.game.domain.KeyInfo;
import com.ff.game.domain.Platform;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.game.service.IPlatformService;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Service
@Order(4)
public class AddBalanceServiceImpl extends AbstractStepProcessor {
@Resource
private IMemberService memberService;
@Resource
private ITenantGameQuotaService tenantGameQuotaService;
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private PlatformTransactionManager transactionManager;
@Resource
private IPlatformService platformService;
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep stepKey() {
return GameExchangeStep.TENANT_QUOTA_DEDUCTED;
}
/**
* do
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doProcess(GameExchangeDTO gameExchangeMoney) {
//如果不是之前的步骤代码执行过了 或者是转入操作
if (!gameExchangeMoney.getStep().equals(GameExchangeStep.PLATFORM_TRANSACTION.getCode()) ) {
return Boolean.TRUE;
}
if (!gameExchangeMoney.getStepStatus().equals(StatusType.SUCCESS.getValue())){
return Boolean.TRUE;
}
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
Boolean result = transactionTemplate.execute(transactionStatus -> {
//不是转入操作
if (!TransferType.ALL.getCode().equals(gameExchangeMoney.getExchangeType())) {
gameExchangeMoney.setStep(GameExchangeStep.DEDUCT_BALANCE.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoney.setStatus(StatusType.SUCCESS.getValue());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
Platform platform = platformService.get(gameExchangeMoney.getPlatformCode());
KeyInfo keyInfo = null;
for (KeyInfo keyData : platform.getKeyInfo()) {
if (StringUtils.isNotEmpty(gameExchangeMoney.getCurrencyCode())) {
if (keyData.getCurrency().equalsIgnoreCase(gameExchangeMoney.getCurrencyCode())) {
keyInfo = keyData;
break;
}
}
}
BigDecimal decimal = tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder()
.platformCode(gameExchangeMoney.getPlatformCode())
.sourceId(String.valueOf(gameExchangeMoney.getId()))
.currencyCode(gameExchangeMoney.getCurrencyCode())
.currency(gameExchangeMoney.getCurrencyCode())
.transferType(gameExchangeMoney.getExchangeType())
.amount(gameExchangeMoney.getBalance())
.isAll(Boolean.FALSE)
.account(memberService.selectMemberById(gameExchangeMoney.getMemberId()).getMemberAccount())
.tenantKey(gameExchangeMoney.getTenantKey())
.systemCurrency(gameExchangeMoney.getCurrencyCode())
.agentId(keyInfo.getCode())
.agentKey(keyInfo.getKey())
.build());
gameExchangeMoney.setQuota(decimal);
gameExchangeMoney.setStep(GameExchangeStep.TENANT_QUOTA_DEDUCTED.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoney.setStatus(StatusType.SUCCESS.getValue());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
});
return Boolean.TRUE.equals(result);
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doRollBack(GameExchangeDTO gameExchangeMoney) {
return Boolean.TRUE;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep nextStepProcessor() {
return null;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep backStepProcessor() {
{
return null;
}
}
}

View File

@ -1,112 +0,0 @@
package com.ff.game.api.exchange.impl;
import com.ff.base.constant.Constants;
import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException;
import com.ff.base.manager.AsyncManager;
import com.ff.base.utils.DateUtils;
import com.ff.base.utils.uuid.IdUtils;
import com.ff.game.api.IGamesService;
import com.ff.game.api.exchange.AbstractStepProcessor;
import com.ff.game.api.exchange.StepProcessorFactory;
import com.ff.game.api.exchange.StepProcessorService;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.api.request.ExchangeTransferStatusRequestDTO;
import com.ff.game.api.request.TransactionIdRequestDTO;
import com.ff.game.domain.GameExchangeMoney;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.member.domain.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Map;
/**
* impl
*
* @author shi
* @date 2025/04/09
*/
@Service
@Order(1)
public class CreateOrderServiceImpl extends AbstractStepProcessor {
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private StepProcessorFactory stepProcessorFactory;
@Autowired
private Map<String, IGamesService> gamesService;
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep stepKey() {
return GameExchangeStep.CREATE_ORDER;
}
/**
* do
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doProcess(GameExchangeDTO gameExchangeMoney) {
String transactionId = gamesService.get(gameExchangeMoney.getPlatformCode()+Constants.SERVICE).getTransactionId(TransactionIdRequestDTO.builder().exchangeType(gameExchangeMoney.getExchangeType()).gameAccount(gameExchangeMoney.getGameAccount()).build());
gameExchangeMoney.setTransactionId(transactionId);
gameExchangeMoney.setCreateBy(Constants.SYSTEM);
gameExchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
gameExchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
return gameExchangeMoneyService.insertGameExchangeMoney(gameExchangeMoney) > 0;
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doRollBack(GameExchangeDTO gameExchangeMoney) {
gameExchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoney.setStatus(StatusType.FAILURE.getValue());
gameExchangeMoney.setUpdateBy(Constants.SYSTEM);
gameExchangeMoney.setUpdateTime(DateUtils.getNowDate());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep nextStepProcessor() {
return GameExchangeStep.DEDUCT_BALANCE;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep backStepProcessor() {
return null;
}
}

View File

@ -1,207 +0,0 @@
package com.ff.game.api.exchange.impl;
import com.ff.base.constant.Constants;
import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException;
import com.ff.base.utils.DateUtils;
import com.ff.base.utils.QuotaUtils;
import com.ff.base.utils.StringUtils;
import com.ff.base.utils.uuid.IdUtils;
import com.ff.common.domain.TenantGameQuota;
import com.ff.common.domain.TenantGameQuotaFlow;
import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.dto.GameBalanceExchange;
import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantGameQuotaService;
import com.ff.game.api.exchange.AbstractStepProcessor;
import com.ff.game.api.exchange.StepProcessorFactory;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.domain.GameExchangeMoney;
import com.ff.game.domain.KeyInfo;
import com.ff.game.domain.Platform;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.game.service.IPlatformService;
import com.ff.member.service.IMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
/**
* impl
*
* @author shi
* @date 2025/04/09
*/
@Service
@Order(2)
public class DeductBalanceServiceImpl extends AbstractStepProcessor {
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private ITenantGameQuotaService tenantGameQuotaService;
@Resource
private IMemberService memberService;
@Resource
private IPlatformService platformService;
@Resource
private ITenantGameQuotaFlowService tenantGameQuotaFlowService;
@Autowired
private PlatformTransactionManager transactionManager;
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep stepKey() {
return GameExchangeStep.DEDUCT_BALANCE;
}
/**
* do
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doProcess(GameExchangeDTO gameExchangeMoney) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
Boolean result = transactionTemplate.execute(transactionStatus -> {
//如果不是之前的步骤代码执行过了
if (!gameExchangeMoney.getStep().equals(this.backStepProcessor().getCode())) {
return Boolean.TRUE;
}
//不是转入操作
if (!TransferType.GAMES.getCode().equals(gameExchangeMoney.getExchangeType())) {
gameExchangeMoney.setStep(GameExchangeStep.DEDUCT_BALANCE.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
Platform platform = platformService.get(gameExchangeMoney.getPlatformCode());
KeyInfo keyInfo = null;
for (KeyInfo keyData : platform.getKeyInfo()) {
if (StringUtils.isNotEmpty(gameExchangeMoney.getCurrencyCode())) {
if (keyData.getCurrency().equalsIgnoreCase(gameExchangeMoney.getCurrencyCode())) {
keyInfo = keyData;
break;
}
}
}
BigDecimal decimal = tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder()
.platformCode(gameExchangeMoney.getPlatformCode())
.sourceId(String.valueOf(gameExchangeMoney.getId()))
.currencyCode(gameExchangeMoney.getCurrencyCode())
.currency(gameExchangeMoney.getCurrencyCode())
.transferType(gameExchangeMoney.getExchangeType())
.amount(gameExchangeMoney.getBalance())
.account(memberService.selectMemberById(gameExchangeMoney.getMemberId()).getMemberAccount())
.tenantKey(gameExchangeMoney.getTenantKey())
.systemCurrency(gameExchangeMoney.getCurrencyCode())
.agentId(keyInfo.getCode())
.isAll(Boolean.TRUE)
.agentKey(keyInfo.getKey())
.build());
gameExchangeMoney.setQuota(decimal);
gameExchangeMoney.setStep(GameExchangeStep.DEDUCT_BALANCE.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
});
return Boolean.TRUE.equals(result);
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doRollBack(GameExchangeDTO gameExchangeMoney) {
//如果不是之前的步骤代码执行过了 或者是转入操作
if (!gameExchangeMoney.getStep().equals(this.stepKey().getCode())) {
return Boolean.TRUE;
}
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
//如果该订单已经回滚过增加余额
List<TenantGameQuotaFlow> tenantGameQuotaFlows = tenantGameQuotaFlowService.selectTenantGameQuotaFlowList(
TenantGameQuotaFlow.builder()
.sourceId(String.valueOf(gameExchangeMoney.getId()))
.isOut(Boolean.TRUE)
.build());
if (!CollectionUtils.isEmpty(tenantGameQuotaFlows)){
return Boolean.TRUE;
}
tenantGameQuotaFlows = tenantGameQuotaFlowService.selectTenantGameQuotaFlowList(
TenantGameQuotaFlow.builder()
.sourceId(String.valueOf(gameExchangeMoney.getId()))
.isOut(Boolean.FALSE)
.build());
if (CollectionUtils.isEmpty(tenantGameQuotaFlows)) {
return Boolean.TRUE;
}
//取出第一个
TenantGameQuotaFlow tenantGameQuotaFlow = tenantGameQuotaFlows.get(0);
return tenantGameQuotaService.balanceChanges(BalanceChangesDTO.builder()
.isOut(Boolean.TRUE)
.platformCode(tenantGameQuotaFlow.getPlatformCode())
.currencyCode(tenantGameQuotaFlow.getCurrencyCode())
.tenantKey(tenantGameQuotaFlow.getTenantKey())
.balance(tenantGameQuotaFlow.getBalance())
.sourceId(tenantGameQuotaFlow.getSourceId())
.memberId(gameExchangeMoney.getMemberId())
.operationType(OperationType.API_BALANCE.getCode())
.remark(OperationType.API_BALANCE.getDescription())
.quotaType(tenantGameQuotaFlow.getQuotaType()).build());
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep nextStepProcessor() {
return GameExchangeStep.PLATFORM_TRANSACTION;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep backStepProcessor() {
{
return GameExchangeStep.CREATE_ORDER;
}
}
}

View File

@ -1,214 +0,0 @@
package com.ff.game.api.exchange.impl;
import com.ff.base.constant.Constants;
import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException;
import com.ff.base.utils.StringUtils;
import com.ff.common.domain.TenantGameQuotaFlow;
import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.dto.GameBalanceExchange;
import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantGameQuotaService;
import com.ff.game.api.IGamesService;
import com.ff.game.api.exchange.AbstractStepProcessor;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.api.request.ExchangeTransferMoneyRequestDTO;
import com.ff.game.api.request.ExchangeTransferStatusRequestDTO;
import com.ff.game.api.request.ExchangeTransferStatusResponseDTO;
import com.ff.game.domain.GameExchangeMoney;
import com.ff.game.domain.KeyInfo;
import com.ff.game.domain.Platform;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.game.service.IPlatformService;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Service
@Order(3)
public class PlatformTransactionServiceImpl extends AbstractStepProcessor {
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private IMemberService memberService;
@Resource
private IPlatformService platformService;
@Autowired
private Map<String, IGamesService> gamesService;
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep stepKey() {
return GameExchangeStep.PLATFORM_TRANSACTION;
}
/**
* do
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doProcess(GameExchangeDTO gameExchangeMoney) {
//如果不是之前的步骤代码执行过了 或者当前步骤成功的
if (!gameExchangeMoney.getStep().equals(this.backStepProcessor().getCode())&&
(GameExchangeStep.PLATFORM_TRANSACTION.getCode().equals(gameExchangeMoney.getStep())&&
gameExchangeMoney.getStepStatus().equals(GameExchangeStepStatus.SUCCESS.getCode()))
) {
return Boolean.TRUE;
}
Platform platform = platformService.get(gameExchangeMoney.getPlatformCode());
String targetCurrency = platform.getCurrencyInfo().get(gameExchangeMoney.getCurrencyCode());
ApiException.notNull(targetCurrency, ErrorCode.CURRENCY_NOT_EXIST.getCode());
KeyInfo keyInfo = null;
for (KeyInfo keyData : platform.getKeyInfo()) {
if (StringUtils.isNotEmpty(gameExchangeMoney.getCurrencyCode())) {
if (keyData.getCurrency().equalsIgnoreCase(gameExchangeMoney.getCurrencyCode())) {
keyInfo = keyData;
break;
}
}
}
Member member = memberService.selectMemberById(gameExchangeMoney.getMemberId());
IGamesService iGamesService = gamesService.get(gameExchangeMoney.getPlatformCode() + Constants.SERVICE);
//查询订单详情
if (TriggerType.TIMER.getCode() == gameExchangeMoney.getTriggerType()) {
//做二次确认调订单详情接口
this.doRollBack(gameExchangeMoney);
if (GameExchangeStepStatus.FAILURE.getCode() == gameExchangeMoney.getStepStatus()){
throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode());
}
}
try {
//操作第三方额度接口
ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO = ExchangeTransferMoneyRequestDTO.builder()
.agentId(keyInfo.getCode())
.agentKey(keyInfo.getKey())
.account(member.getGameAccount())
.currency(targetCurrency)
.amount(gameExchangeMoney.getBalance())
.transferType(gameExchangeMoney.getExchangeType())
.transactionId(gameExchangeMoney.getTransactionId())
.gameExchangeId(gameExchangeMoney.getId())
.vendor(platform)
.keyInfo(keyInfo)
.build();
Long id = iGamesService.exchangeTransferByAgentId(exchangeTransferMoneyRequestDTO);
}catch (Exception e){
//做二次确认调订单详情接口
this.doRollBack(gameExchangeMoney);
if (GameExchangeStepStatus.FAILURE.getCode() == gameExchangeMoney.getStepStatus()){
throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode());
}
}
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(gameExchangeMoney.getId());
gameExchangeMoney.setBalance(exchangeMoney.getBalance());
gameExchangeMoney.setStep(exchangeMoney.getStep());
gameExchangeMoney.setStepStatus(exchangeMoney.getStepStatus());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doRollBack(GameExchangeDTO gameExchangeMoney) {
Platform platform = platformService.get(gameExchangeMoney.getPlatformCode());
String targetCurrency = platform.getCurrencyInfo().get(gameExchangeMoney.getCurrencyCode());
ApiException.notNull(targetCurrency, ErrorCode.CURRENCY_NOT_EXIST.getCode());
KeyInfo keyInfo = null;
for (KeyInfo keyData : platform.getKeyInfo()) {
if (StringUtils.isNotEmpty(gameExchangeMoney.getCurrencyCode())) {
if (keyData.getCurrency().equalsIgnoreCase(gameExchangeMoney.getCurrencyCode())) {
keyInfo = keyData;
break;
}
}
}
Member member = memberService.selectMemberById(gameExchangeMoney.getMemberId());
IGamesService iGamesService = gamesService.get(gameExchangeMoney.getPlatformCode() + Constants.SERVICE);
ExchangeTransferStatusRequestDTO exchangeTransferStatusRequestDTO = new ExchangeTransferStatusRequestDTO();
exchangeTransferStatusRequestDTO.setAccount(member.getGameAccount());
exchangeTransferStatusRequestDTO.setCurrency(targetCurrency);
exchangeTransferStatusRequestDTO.setOrderId(gameExchangeMoney.getTransactionId());
exchangeTransferStatusRequestDTO.setAgentId(keyInfo.getCode());
exchangeTransferStatusRequestDTO.setAgentKey(keyInfo.getKey());
exchangeTransferStatusRequestDTO.setGameExchangeMoneyId(gameExchangeMoney.getId());
exchangeTransferStatusRequestDTO.setVendor(platform);
exchangeTransferStatusRequestDTO.setKeyInfo(keyInfo);
exchangeTransferStatusRequestDTO.setSystemCurrency(gameExchangeMoney.getCurrencyCode());
ExchangeTransferStatusResponseDTO statusResponseDTO = iGamesService.exchangeTransferStatus(exchangeTransferStatusRequestDTO);
//订单已成功
if (StatusType.SUCCESS.getValue().equals(statusResponseDTO.getStatusType())) {
gameExchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
gameExchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep nextStepProcessor() {
return GameExchangeStep.TENANT_QUOTA_DEDUCTED;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep backStepProcessor() {
{
return GameExchangeStep.DEDUCT_BALANCE;
}
}
}

View File

@ -1,30 +0,0 @@
package com.ff.game.api.fb.address;
import com.dtflys.forest.callback.AddressSource;
import com.dtflys.forest.http.ForestAddress;
import com.dtflys.forest.http.ForestRequest;
import com.ff.base.enums.GamePlatforms;
import com.ff.game.service.IPlatformService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <a href="https://doc.newsportspro.com/apidoc_data.html#%E5%85%A5%E5%8F%82"></a>
*
* @author cengy
*/
@Component
public class FBSportsAddress implements AddressSource {
@Resource
private IPlatformService platformService;
@Override
public ForestAddress getAddress(ForestRequest request) {
String apiBaseUrl = platformService.get(GamePlatforms.FBSports.getCode())
.getUrlInfo().getUrl();
return new ForestAddress("https", apiBaseUrl, 443, "fb/data");
}
}

View File

@ -1,102 +0,0 @@
package com.ff.game.api.fb.client;
import com.dtflys.forest.annotation.*;
import com.ff.game.api.fb.address.FBSportsAddress;
import com.ff.game.api.fb.dto.*;
/**
* <a href="https://doc.newsportspro.com/apidoc_data.html"></a><br/>
* <a href="https://doc.newsportspro.com/h5_pc_doc.html"></a>
*
* @author cengy
*/
@Address(source = FBSportsAddress.class)
public interface FBSportsClient {
/**
*
*
* @return {@link CreateUserResponse}
*/
@Post(url = "/api/v2/new/user/create")
CreateUserResponse createMember(@JSONBody CreateUserRequest request,
@Header("sign") @Var("sign") String sign,
@Header("timestamp") @Var("timestamp") long timestamp,
@Header("merchantId") @Var("merchantId") String merchantId);
/**
* FB0.01
*
* @param request
* @param sign
* @param timestamp
* @param merchantId
* @return {@link TransferInResponse}
*/
@Post(url = "/api/v2/new/transfer/in")
TransferInResponse transferIn(@JSONBody TransferInRequest request,
@Header("sign") @Var("sign") String sign,
@Header("timestamp") @Var("timestamp") long timestamp,
@Header("merchantId") @Var("merchantId") String merchantId);
@Post(url = "/api/v2/new/transfer/out")
TransferOutResponse transferOut(@JSONBody TransferOutRequest request,
@Header("sign") @Var("sign") String sign,
@Header("timestamp") @Var("timestamp") long timestamp,
@Header("merchantId") @Var("merchantId") String merchantId);
@Post(url = "/api/v2/new/user/detail")
GetMemberInfoResponse getMemberInfo(@JSONBody GetMemberInfoRequest request,
@Header("sign") @Var("sign") String sign,
@Header("timestamp") @Var("timestamp") long timestamp,
@Header("merchantId") @Var("merchantId") String merchantId);
/**
* /
*/
@Post(url = "/api/v2/transfer/detail")
TransferDetailResponse transferDetail(@JSONBody TransferDetailRequest request,
@Header("sign") @Var("sign") String sign,
@Header("timestamp") @Var("timestamp") long timestamp,
@Header("merchantId") @Var("merchantId") String merchantId);
@Post(url = "/api/v2/service/domain/list")
GetUrlResponse getUrl(@JSONBody GetUrlRequest request,
@Header("sign") @Var("sign") String sign,
@Header("timestamp") @Var("timestamp") long timestamp,
@Header("merchantId") @Var("merchantId") String merchantId);
/**
* FBFB5
* IDID
*/
@Post(url = "/api/v2/order/file/ids")
OrderFilesResponse orderFiles(@JSONBody OrderFilesRequest request,
@Header("sign") @Var("sign") String sign,
@Header("timestamp") @Var("timestamp") long timestamp,
@Header("merchantId") @Var("merchantId") String merchantId);
/**
* Json
*/
@Post(url = "/api/v2/order/list")
OrderInfoResponse getOrderJsonData(@JSONBody OrderInfoRequest request,
@Header("sign") @Var("sign") String sign,
@Header("timestamp") @Var("timestamp") long timestamp,
@Header("merchantId") @Var("merchantId") String merchantId);
/**
* apptokenurltokenapp
*
* @param request
* @param sign
* @param timestamp
* @param merchantId
* @return
*/
@Post(url = "/api/v2/token/get")
GetTokenResponse getToken(@JSONBody GetTokenRequest request,
@Header("sign") @Var("sign") String sign,
@Header("timestamp") @Var("timestamp") long timestamp,
@Header("merchantId") @Var("merchantId") String merchantId);
}

View File

@ -1,30 +0,0 @@
package com.ff.game.api.fb.dto;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author cengy
*/
@Data
public class CreateUserRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String merchantUserId;// 渠道用户id支持40位字符串必须唯一
private List<Integer> currencyIds = null; // 币种id集合 , see enum: currency
private Integer oddsLevel = null; // 赔率级别,不传则为默认, see enum: user_odds_level_enum
public String toJSON() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("currencyIds", currencyIds);
map.put("merchantUserId", merchantUserId);
map.put("oddsLevel", oddsLevel);
return JSON.toJSONString(map);
}
}

View File

@ -1,19 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class CreateUserResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean success;
private Integer data;
private Integer code;
private String message;
}

View File

@ -1,9 +0,0 @@
package com.ff.game.api.fb.dto;
/**
* @author cengy
*/
public class Enums {
}

View File

@ -1,27 +0,0 @@
package com.ff.game.api.fb.dto;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author cengy
*/
@Data
public class GetMemberInfoRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id,
*/
private String merchantUserId;
public String toJSON() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("merchantUserId", merchantUserId);
return JSON.toJSONString(map);
}
}

View File

@ -1,38 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @author cengy
*/
@Data
public class GetMemberInfoResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean success;
private String message;
private MemberInfo data;
private Integer code;
@Data
public static class MemberInfo implements Serializable{
private static final long serialVersionUID = 1L;
private String merchantUserId;
private Integer userId; // FB体育用户id
private Integer walletType; // 用户钱包类型 , see enum: wallet_type
private Integer currencyType; // 用户币种类型 , see enum: currency_type
private List<Wallet> wallets; // 钱包集合
private Integer oddsLevel;// 赔率级别 , see enum: user_odds_level_enum
}
@Data
public static class Wallet implements Serializable{
private static final long serialVersionUID = 1L;
private Integer currencyType; // 币种类型 , see enum: currency_type
private BigDecimal balance; // 余额
private Integer currencyId; // 币种id , see enum: currency
}
}

View File

@ -1,30 +0,0 @@
package com.ff.game.api.fb.dto;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author cengy
*/
@Data
public class GetTokenRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String merchantUserId;
// 平台类型pch5, mobile , see enum: plat_form_enum
private String platForm;
// 客户端用户ip地址尽可能提供我们用于风控
private String ip; // 可选
public String toJSON() {
Map<String, String> map = new LinkedHashMap<>();
map.put("merchantUserId", merchantUserId);
map.put("platForm", platForm);
return JSON.toJSONString(map);
}
}

View File

@ -1,49 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author cengy
*/
@Data
public class GetTokenResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean success;
private String message;
private Integer code;
private TokenDTO data;
@Data
public static class TokenDTO implements Serializable {
private String token; // 用户鉴权token用于客户端鉴权
private ServerInfo serverInfo; // 服务器地址信息
private List<Domain> domains; // 全部服务器地址信息
private String themeBgColor; // 主题背景色
private String themeFgColor; // 主题前景色
private Integer userId; // FB用户ID
}
@Data
public static class ServerInfo implements Serializable {
private static final long serialVersionUID = 1L;
private String apiServerAddress; // app接口服务地址
private String apiEmbeddedServerAddress; // app内嵌网页地址
private String pushServerAddress; // 推送服务地址
private String pcAddress; // PC投注网站地址
private String h5Address; // h5投注网站地址
private String virtualAddress; // 虚拟体育投注网站地址
private String virtualMatchVideoAddress; // 虚拟赛事视频地址
private String ouH5Address; // 欧版h5地址
private String ouPcAddress; // 欧版pc地址
}
@Data
public static class Domain {
private Integer type; // 域名类型
private List<String> domains; // 域名集合
}
}

View File

@ -1,17 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author cengy
*/
@Data
public class GetUrlRequest implements Serializable {
private static final long serialVersionUID = 1L;
public String toJSON() {
return "{}";
}
}

View File

@ -1,33 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author cengy
*/
@Data
public class GetUrlResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean success;
private String message;
private List<UrlDTO> data;
private Integer code;
@Data
public static class UrlDTO implements Serializable {
private static final long serialVersionUID = 1L;
private int type; //域名类型1API2PUSH3H54PC5IMAGE , see enum: domain_type_enum
private List<DomainDTO> domainList; // 域名集合
}
@Data
public static class DomainDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String domain; // 域名
private int weight; // 权限值
}
}

View File

@ -1,41 +0,0 @@
package com.ff.game.api.fb.dto;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author cengy
*/
@Data
public class OrderFilesRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 13,null
*/
private Long startTime;
/**
* 13,null
*/
private Long endTime;
public String toJSON() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("endTime", endTime);
map.put("startTime", startTime);
return JSON.toJSONString(map);
// String endTimeStr = endTime ; // 转换为字符串
// String startTimeStr = startTime; // 转换为字符串
//
// String json = "{" +
// "\"endTime\": \"" + endTimeStr + "\", " +
// "\"startTime\": \"" + startTimeStr + "\"" +
// "}";
// return json;
}
}

View File

@ -1,27 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author cengy
*/
@Data
public class OrderFilesResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean success;
private String message;
private Integer code;
private List<FileId> data;
@Data
public static class FileId implements Serializable {
private static final long serialVersionUID = 1L;
private Long fileId;
}
}

View File

@ -1,26 +0,0 @@
package com.ff.game.api.fb.dto;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author cengy
*/
@Data
public class OrderInfoRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Id/order/file/ids
*/
private Long fileId;
public String toJSON() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("fileId", fileId);
return JSON.toJSONString(map);
}
}

View File

@ -1,115 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author cengy
*/
@Data
public class OrderInfoResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean success;
private String message;
private Integer code;
private List<OrderDTO> data;
@Data
public static class OrderDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String id; // 订单号
private Integer rejectReason; // 拒单原因码 see enum: order_reject_type
private String rejectReasonStr; // 拒单原因
private String userId; // FB平台用户ID
private String merchantId; // 渠道ID
private String merchantUserId; // 渠道用户ID
private Integer currency; // 币种 see enum: currency
private String exchangeRate; // 汇率快照
private Integer seriesType; // 关次类型 0 单关、1 串关, see enum: series_type
private String betType; // 投注类型
private Integer allUp; // 总关数
private Integer allUpAlive; // 存活关数
private String stakeAmount; // 投注额(本金)
private String liabilityStake; // 名义投注额(名义本金)
private String settleAmount; // 结算派奖金额
private Integer orderStatus; // 订单状态 see enum: order_status
private Integer payStatus; // 付款状态
private Integer oddsChange; // 是否接受赔率变更 0不接受1 接受更好赔率2接受任意赔率 , see enum: odds_change_enum
private String device; // 设备类型 pc、h5、mobile) , see enum: plat_form_enum
private String ip; // 投注IP地址
private String settleTime; // 订单结算时间
private String createTime; // 订单创建时间
private String modifyTime; // 订单确认时间
private String cancelTime; // 订单取消时间
private String thirdRemark; // 第三方备注
private String relatedId; // 三方关联ID
private String maxWinAmount; // 最大可赢金额
private String loseAmount; // 最大赔付金额
private Integer rollBackCount; // 回滚次数
private Integer itemCount; // 选项数
private Integer seriesValue; // 串几关
private Integer betNum; // 子单数
private String cashOutTotalStake; // 提前结算总本金
private String liabilityCashoutStake; // 提前结算名义总本金
private String cashOutPayoutStake; // 提前结算总派奖额
private String reserveId; // 预约订单单号
private Integer cashOutCount; // 提前结算次数
private String unitStake; // 每单金额
private Integer reserveVersion; // 预约订单版本号
private List<BetDTO> betList; // 注单集合
}
@Data
public static class BetDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String id; // ID
private String orderId; // 订单ID
private Integer sportId; // 运动ID
private String matchId; // 比赛ID
private String matchName; // 比赛名称
private Integer period; // 阶段ID
private String marketId; // 玩法ID
private Integer marketType; // 玩法类型
private Integer optionType; // 投注项类型
private String optionName; // 选项名称
private String marketName; // 玩法名称
private String tournamentId; // 联赛ID
private String tournamentName; // 联赛名称
private String odds; // 欧式赔率
private Integer oddsFormat; // 投注时赔率类型
private String betOdds; // 投注时赔率
private Integer settleStatus; // 结算状态
private Integer settleResult; // 结算结果
private Boolean isInplay; // 是否滚球
private String remark; // 备注
private Double p1; // 变量1 (例如:让几个球)
private Double p2; // 变量2
private Double p3; // 变量3
private String extendedParameter; // 亚洲让球线
private String extraInfo; // 当前比分
private String pendingTime; // 延迟等待时间
private String betScore; // 下注当时比分
private Integer cancelReason; // 取消原因
private String cancelReasonName; // 取消原因文本
private Integer matchType; // 赛事类型
private String matchTime; // 开赛时间
private Integer virtualMatchDay; // 轮次
private Integer virtualChampId; // 赛季
private Integer virtualLegOrder; // 淘汰赛回合
private Integer virtualWeekDay; // 小组赛比赛日
private Integer virtualBlockId; // 期
private Integer leaguePhase; // 联赛阶段
private String maxStake; // 最大投注额
private String validSettleStakeAmount; // 有效已结算投注额
private String validSettleAmount; // 有效返还额
private String cashOutCancelStake; // 提前结算取消总额
private Integer walletType; // 钱包类型
private Integer version; // 数据变更标记
}
}

View File

@ -1,39 +0,0 @@
package com.ff.game.api.fb.dto;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author cengy
*/
@Data
public class TransferDetailRequest implements Serializable {
/**
* id,null
*/
private String businessId;
/**
* ID,null
*/
private String merchantUserId;
/**
* , see enum: transfer_type_enum
*/
private String transferType;
public String toJSON() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("businessId", businessId);
map.put("merchantUserId", merchantUserId);
map.put("transferType", transferType);
return JSON.toJSONString(map);
}
}

View File

@ -1,39 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author cengy
*/
@Data
public class TransferDetailResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean success;
private String message;
private TransferDetail data;
private Integer code;
@Data
public static class TransferDetail implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private Integer userId;
private String merchantUserId;
private String businessId;
// IN 转入
// OUT 转出
private String transferType;
private BigDecimal beforeTransferAmount;
private BigDecimal afterTransferAmount;
private Integer status; // 状态 , see enum: transfer_status_enum, 1 Successful 0 Failure
private Long createTime; // 记录创建时间
private Integer currencyId;// 币种id , see enum: currency
}
}

View File

@ -1,46 +0,0 @@
package com.ff.game.api.fb.dto;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author cengy
*/
@Data
public class TransferInRequest implements Serializable {
/**
* ,null
* 0
*/
private BigDecimal amount;
/**
* id,null
*/
private String businessId;
/**
* ID,null
*/
private String merchantUserId;
/**
* id,
*/
private Integer currencyId;
public String toJSON() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("amount", amount);
map.put("businessId", businessId);
map.put("currencyId", currencyId);
map.put("merchantUserId", merchantUserId);
return JSON.toJSONString(map);
}
}

View File

@ -1,20 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author cengy
*/
@Data
public class TransferInResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean success;
private BigDecimal data;
private Integer code;
private String message;
}

View File

@ -1,46 +0,0 @@
package com.ff.game.api.fb.dto;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author cengy
*/
@Data
public class TransferOutRequest implements Serializable {
/**
* ,null
* 0
*/
private BigDecimal amount;
/**
* id,null
*/
private String businessId;
/**
* ID,null
*/
private String merchantUserId;
/**
* id,
*/
private Integer currencyId;
public String toJSON() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("amount", amount);
map.put("businessId", businessId);
map.put("currencyId", currencyId);
map.put("merchantUserId", merchantUserId);
return JSON.toJSONString(map);
}
}

View File

@ -1,20 +0,0 @@
package com.ff.game.api.fb.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author cengy
*/
@Data
public class TransferOutResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Boolean success;
private BigDecimal data;
private Integer code;
private String message;
}

View File

@ -1,753 +0,0 @@
package com.ff.game.api.fb.impl;
import cn.hutool.core.util.IdUtil;
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.utils.DateUtils;
import com.ff.base.utils.StringUtils;
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.fb.dto.*;
import com.ff.game.api.request.*;
import com.ff.game.domain.*;
import com.ff.game.service.IGameBettingDetailsService;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.game.service.IGameService;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import com.ff.game.api.fb.client.FBSportsClient;
import com.ff.utils.TimestampFromString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* FB
*
* @author shi
* @date 2024/10/21
*/
@Service("FBSportsService")
@Slf4j
public class FBSportsServiceImpl implements IGamesService {
@Resource
private RedisCache redisCache;
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private IGameService gameService;
@Resource
private IMemberService memberService;
@Resource
private FBSportsClient fbSportsClient;
@Resource
private IGameBettingDetailsService gameBettingDetailsService;
/**
*
*
* @param errorCode
* @return {@link Boolean }
*/
private Boolean isSuccess(Integer errorCode) {
return 0 == errorCode;
}
String getSign(String bodyJsonString, String merchantId, String merchantApiSecret, long requestTimestamp) {
String stringThatNeedsToBeSigned = bodyJsonString + "." + merchantId + "." + requestTimestamp + "." + merchantApiSecret;
String sign = Md5Utils.md5New(stringThatNeedsToBeSigned);
return sign;
}
/**
*
*
* @param createMemberRequestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) {
long timestamp = System.currentTimeMillis();
CreateUserRequest request = new CreateUserRequest();
request.setMerchantUserId(createMemberRequestDTO.getAccount());
ArrayList<Integer> currencyIds = new ArrayList<>();
currencyIds.add(Integer.parseInt(createMemberRequestDTO.getCurrency()));
request.setCurrencyIds(currencyIds);
String jsonBody = /*SortByAttributeNameASC.get(request)*/ request.toJSON();
String sign = getSign(jsonBody,
createMemberRequestDTO.getAgentId(),
createMemberRequestDTO.getAgentKey(),
timestamp
);
CreateUserResponse response = fbSportsClient.createMember(
request,
sign,
timestamp, createMemberRequestDTO.getAgentId());
if (isSuccess(response.getCode())) {
log.info("创建会员成功, account:{}->{}", createMemberRequestDTO.getAccount(), response.getData());
return Boolean.TRUE;
}
log.error("创建会员失败, errorCode:{}, errorMessage:{}", response.getCode(), response.getMessage());
throw new ApiException(ErrorCode.Create_Member_Failure.getCode());
}
/**
* id
*
* @param requestDTO moeny dto
* @return {@link Long }
*/
@Override
@Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO requestDTO) {
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(requestDTO.getGameExchangeId());
// 转入
if (requestDTO.getTransferType().equals(TransferType.GAMES.getCode())) {
TransferInRequest request = new TransferInRequest();
request.setMerchantUserId(requestDTO.getAccount());
request.setAmount(requestDTO.getAmount());
request.setBusinessId(requestDTO.getTransactionId());
request.setCurrencyId(Integer.parseInt(requestDTO.getCurrency()));
long timestamp = System.currentTimeMillis();
String jsonBody = request.toJSON();
String sign = getSign(jsonBody,
requestDTO.getAgentId(),
requestDTO.getAgentKey(),
timestamp
);
TransferInResponse response = fbSportsClient.transferIn(
request,
sign,
timestamp,
requestDTO.getAgentId());
if (isSuccess(response.getCode())) {
BigDecimal transAmount = requestDTO.getAmount();
exchangeMoney.setBalance(transAmount);
exchangeMoney.setCoinBefore(response.getData().subtract(transAmount));
exchangeMoney.setCoinAfter(response.getData());
exchangeMoney.setCurrencyBefore(response.getData().subtract(transAmount));
exchangeMoney.setCurrencyAfter(response.getData());
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
throw new ApiException(ErrorCode.Transfer_In_Failure.getCode());
}
} else {
// 获取第三方钱包余额
MemberInfoRequestDTO memberInfoRequestDTO = MemberInfoRequestDTO.builder()
.accounts(requestDTO.getAccount())
.agentId(requestDTO.getAgentId())
.agentKey(requestDTO.getAgentKey())
.build();
BigDecimal balance = this.getMemberInfo(memberInfoRequestDTO).getBalance();
TransferOutRequest request = new TransferOutRequest();
request.setMerchantUserId(requestDTO.getAccount());
request.setAmount(/*requestDTO.getAmount()*/ balance);
request.setBusinessId(requestDTO.getTransactionId());
request.setCurrencyId(Integer.parseInt(requestDTO.getCurrency()));
long timestamp = System.currentTimeMillis();
String jsonBody = request.toJSON();
String sign = getSign(jsonBody,
requestDTO.getAgentId(),
requestDTO.getAgentKey(),
timestamp
);
TransferOutResponse response = fbSportsClient
.transferOut(
request,
sign,
timestamp,
requestDTO.getAgentId()
);
//判断是否转移成功
if (this.isSuccess(response.getCode())) {
BigDecimal transAmount = balance;
//更新数据
exchangeMoney.setBalance(transAmount);
exchangeMoney.setCoinBefore(response.getData().add(transAmount));
exchangeMoney.setCoinAfter(response.getData());
exchangeMoney.setCurrencyBefore(response.getData().add(transAmount));
exchangeMoney.setCurrencyAfter(response.getData());
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
throw new ApiException(ErrorCode.Transfer_Out_Failure.getCode());
}
}
return exchangeMoney.getId();
}
/**
*
*
* @param requestDTO dto
* @return {@link MemberInfoResponseDTO }
*/
@Override
public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO requestDTO) {
GetMemberInfoRequest request = new GetMemberInfoRequest();
request.setMerchantUserId(requestDTO.getAccounts());
long timestamp = System.currentTimeMillis();
String jsonBody = request.toJSON();
String sign = getSign(jsonBody,
requestDTO.getAgentId(),
requestDTO.getAgentKey(),
timestamp
);
GetMemberInfoResponse response = fbSportsClient.getMemberInfo(
request,
sign,
timestamp,
requestDTO.getAgentId()
);
//判断是否获取成功
if (this.isSuccess(response.getCode())) {
BigDecimal balance = new BigDecimal("0.00");
for (GetMemberInfoResponse.Wallet wallet : response.getData().getWallets()) {
balance = balance.add(wallet.getBalance());
}
return MemberInfoResponseDTO.builder()
.status(GameMemberStatus.UNKNOWN.getCode())
.balance(balance)
.account(requestDTO.getAccounts())
.build();
} else {
throw new ApiException(ErrorCode.Get_Member_Info_Failure.getCode());
}
}
/**
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
@Override
public String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO) {
return GamePlatforms.FBSports.getCode() + IdUtils.simpleUUID();
}
/**
*
*
* @param requestDTO
* @return {@link String }
*/
@Override
public String loginWithoutRedirect(GamesLogin requestDTO) {
GetTokenRequest request = new GetTokenRequest();
request.setMerchantUserId(requestDTO.getAccount());
request.setPlatForm(/*requestDTO.getPlatform()*/ "mobile"); // pch5, mobile , see enum: plat_form_enum
long timestamp = System.currentTimeMillis();
String jsonBody = request.toJSON();
String sign = getSign(jsonBody,
requestDTO.getAgentId(),
requestDTO.getAgentKey(),
timestamp
);
GetTokenResponse response = fbSportsClient.getToken(
request,
sign,
timestamp,
requestDTO.getAgentId()
);
if (this.isSuccess(response.getCode())) {
String token = response.getData().getToken();
Integer userId = response.getData().getUserId();
GetTokenResponse.ServerInfo serverInfo = response.getData().getServerInfo();
String h5Address = serverInfo.getH5Address();
if (StringUtils.isEmpty(h5Address)) {
throw new ApiException(ErrorCode.Get_Url_Failure.getCode());
}
return h5Address +
"/index.html#/" +
"?token=" +
token +
"&nickname=" +
userId +
"&apiSrc=" +
serverInfo.getApiServerAddress() +
"&pushSrc=" +
serverInfo.getPushServerAddress() +
"&virtualSrc=" +
serverInfo.getVirtualAddress() +
"&platformName=XK体育";
}
/*GetUrlRequest request = new GetUrlRequest();
long timestamp = System.currentTimeMillis();
String jsonBody = request.toJSON();
String sign = getSign(jsonBody,
requestDTO.getAgentId(),
requestDTO.getAgentKey(),
timestamp
);
GetUrlResponse response = fbSportsClient.getUrl(
request,
sign,
timestamp,
requestDTO.getAgentId()
);
//判断是否获取成功
if (this.isSuccess(response.getCode())) {
List<GetUrlResponse.UrlDTO> urlDTOS = new ArrayList<>();
for (GetUrlResponse.UrlDTO urlDTO : response.getData()) {
if (urlDTO.getType() == 3) { // 3:h5
urlDTOS.add(urlDTO);
}
}
if (urlDTOS.isEmpty()){
throw new ApiException(ErrorCode.Get_Url_Failure.getCode());
}
int randomIndex = new Random().nextInt(urlDTOS.size());
GetUrlResponse.UrlDTO urlDTO = urlDTOS.get(randomIndex);
Collections.shuffle(urlDTO.getDomainList());
return urlDTO.getDomainList().get(0).getDomain();
}*/
throw new ApiException(ErrorCode.Get_Url_Failure.getCode());
}
private static final Long GAME_ID = 11111L;
/**
*
*
* @param gamesBaseRequestDTO dto
* @return {@link String }
*/
@Transactional
@Override
public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) {
Platform platform = gamesBaseRequestDTO.getVendor();
Game game = gameService.selectGameById(GAME_ID);
//不存在这个游戏
if (ObjectUtils.isEmpty(game)) {
game = new Game();
game.setId(/*IdUtil.getSnowflakeNextId()*/GAME_ID);
game.setSortNo(1);
//game.setPlatformId(gamePlatform.getId());
game.setPlatformCode(platform.getPlatformCode());
game.setPlatformType(PlatformType.SPORTS.getCode());
game.setGameCode("1");
game.setGameSourceType(String.valueOf(1));
game.setGameName("FB体育");
game.setCreateBy(Constants.SYSTEM);
NameInfo nameInfo = new NameInfo();
nameInfo.setLang("zh-CN");
nameInfo.setName("FB体育");
game.setNameInfo(Collections.singletonList(nameInfo));
gameService.insertGame(game);
}
/*GameName gameName = gameNameService.selectGameNameById(GAME_NAME_ID);
if (ObjectUtils.isEmpty(gameName)) {
gameNameService.insertGameName(GameName.builder()
.id(GAME_NAME_ID)
.gameId(game.getId())
.gameName(game.getGameName())
.langCode("zh-CN")
.createBy(Constants.SYSTEM)
.build());
}*/
return CacheConstants.FB_Sports;
}
/**
*
*
* @param requestDTO dto
* @return {@link Boolean }
*/
@Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO requestDTO) {
GameExchangeMoney gameExchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(requestDTO.getGameExchangeMoneyId());
if (null == gameExchangeMoney) {
throw new ApiException(ErrorCode.Transfer_Not_Exist.getCode());
}
Integer status = StatusType.IN_PROGRESS.getValue();
if (!Objects.equals(gameExchangeMoney.getStatus(), StatusType.SUCCESS.getValue())) {
TransferDetailRequest request = new TransferDetailRequest();
request.setMerchantUserId(requestDTO.getAccount());
request.setTransferType(Objects.equals(gameExchangeMoney.getExchangeType(), TransferType.GAMES.getCode())
? "IN" : "OUT");
long timestamp = System.currentTimeMillis();
String jsonBody = request.toJSON();
String sign = getSign(jsonBody,
requestDTO.getAgentId(),
requestDTO.getAgentKey(),
timestamp
);
TransferDetailResponse response = fbSportsClient.transferDetail(
request,
sign,
timestamp,
requestDTO.getAgentId()
);
if (this.isSuccess(response.getCode())) {
status = StatusType.SUCCESS.getValue();
} else {
status = StatusType.FAILURE.getValue();
}
}
return ExchangeTransferStatusResponseDTO.builder()
.statusType(status)
.balance(gameExchangeMoney.getBalance())
.coinBefore(gameExchangeMoney.getCoinBefore())
.coinAfter(gameExchangeMoney.getCoinAfter())
.build();
}
/**
*
*
* @param requestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO requestDTO) {
Long lend = requestDTO.getEndTime();
Long lstart = requestDTO.getStartTime();
//betRecordByTimeDTO.setStartTime(lstart);
//betRecordByTimeDTO.setEndTime(lend);
OrderFilesRequest request = new OrderFilesRequest();
request.setStartTime(lstart);
request.setEndTime(lend);
long timestamp = System.currentTimeMillis();
String jsonBody = request.toJSON();
String sign = getSign(jsonBody,
requestDTO.getAgentId(),
requestDTO.getAgentKey(),
timestamp
);
OrderFilesResponse orderFilesResponse = fbSportsClient.orderFiles(
request,
sign,
timestamp,
requestDTO.getAgentId()
);
if (this.isSuccess(orderFilesResponse.getCode())) {
for (OrderFilesResponse.FileId fileId : orderFilesResponse.getData()) {
try {
getOrderData(fileId.getFileId(), requestDTO);
} catch (Exception e) {
log.error("获取订单数据失败,fileId:{},agentId:{}", fileId, requestDTO.getAgentId());
}
}
return true;
}
log.error("获取订单文件失败,agentId:{}", requestDTO.getAgentId());
return false;
}
void getOrderData(Long fileId, BetRecordByTimeDTO requestDTO) {
OrderInfoRequest request = new OrderInfoRequest();
request.setFileId(fileId);
long timestamp = System.currentTimeMillis();
String jsonBody = request.toJSON();
String sign = getSign(jsonBody,
requestDTO.getAgentId(),
requestDTO.getAgentKey(),
timestamp
);
OrderInfoResponse orderInfoResponse = fbSportsClient.getOrderJsonData(
request,
sign,
timestamp,
requestDTO.getAgentId()
);
if (!this.isSuccess(orderInfoResponse.getCode())) {
return;
}
List<OrderInfoResponse.OrderDTO> settledOrderList = new ArrayList<>();
for (OrderInfoResponse.OrderDTO orderDTO : orderInfoResponse.getData()) {
// 0 Created 未确认
// 1 Confirming 确认中
// 2 Rejected 已拒单
// 3 Canceled 已取消
// 4 Confirmed 已接单
// 5 Settled 已结算
if (!orderDTO.getOrderStatus().equals(5)) { // 已结算
continue;
}
settledOrderList.add(orderDTO);
}
this.batchInsert(settledOrderList, requestDTO);
}
/**
*
*
* @param requestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO requestDTO) {
Long lend = requestDTO.getEndTime();
Long lstart = requestDTO.getStartTime();
//betRecordByTimeDTO.setStartTime(lstart);
//betRecordByTimeDTO.setEndTime(lend);
OrderFilesRequest request = new OrderFilesRequest();
request.setStartTime(lstart);
request.setEndTime(lend);
long timestamp = System.currentTimeMillis();
String jsonBody = request.toJSON();
String sign = getSign(jsonBody,
requestDTO.getAgentId(),
requestDTO.getAgentKey(),
timestamp
);
OrderFilesResponse orderFilesResponse = fbSportsClient.orderFiles(
request,
sign,
timestamp,
requestDTO.getAgentId()
);
if (this.isSuccess(orderFilesResponse.getCode())) {
for (OrderFilesResponse.FileId fileId : orderFilesResponse.getData()) {
try {
getOrderData(fileId.getFileId(), requestDTO);
} catch (Exception e) {
log.error("获取订单数据失败,fileId:{},agentId:{}", fileId, requestDTO.getAgentId());
}
}
return true;
}
log.error("获取订单文件失败,agentId:{}", requestDTO.getAgentId());
return false;
}
/**
*
*
* @param createFreeSpinRequest
* @return {@link Boolean }
*/
@Override
public Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest) {
throw new BaseException("暂不支持免费局数");
}
/**
*
*
* @param getGameDetailRequestDTO dto
* @return {@link GetGameDetailResponseDTO }
*/
@Override
public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param kickMemberRequestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) {
return Boolean.FALSE;
}
/**
*
*
* @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 gameDemoLoginRequestDTO dto
* @return {@link GameDemoLoginResponseDTO }
*/
@Override
public GameDemoLoginResponseDTO gameDemoLogin(GameDemoLoginRequestDTO gameDemoLoginRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param settledOrderList
*/
private void batchInsert(List<OrderInfoResponse.OrderDTO> settledOrderList, BetRecordByTimeDTO betRecordByTimeDTO) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<String> wagersIds = new ArrayList<>();
//数据组装
List<OrderInfoResponse.OrderDTO> dataList = settledOrderList;
if (CollectionUtils.isEmpty(dataList)) {
return;
}
//数据转化
for (OrderInfoResponse.OrderDTO dataBean : dataList) {
GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder()
.platform(betRecordByTimeDTO.getVendor())
.data(dataBean).build());
if (!ObjectUtils.isEmpty(bettingDetails)) {
bettingDetails.setId(IdUtil.getSnowflakeNextId());
gameBettingDetails.add(bettingDetails);
}
wagersIds.add(dataBean.getId());
}
if (CollectionUtils.isEmpty(gameBettingDetails)) {
return;
}
//查询重复数据id
List<String> removeWagersIds = gameBettingDetailsService
.selectGameBettingDetailsByWagersId(wagersIds, GamePlatforms.FBSports.getCode());
//用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) {
//转化类
OrderInfoResponse.OrderDTO dataBean = (OrderInfoResponse.OrderDTO) gamesDataBuildDTO.getData();
Member member = memberService.selectMemberByGameAccount(dataBean.getMerchantUserId());
if (ObjectUtils.isEmpty(member)) {
return null;
}
List<Game> gameList = redisCache.getCacheList(CacheConstants.FB_Sports);
Game game = gameList.get(0);
BigDecimal originPayoffAmount = new BigDecimal(dataBean.getSettleAmount());
BigDecimal betAmount = new BigDecimal(dataBean.getStakeAmount());
int compareResult = originPayoffAmount.compareTo(betAmount);
long payoffTime = TimestampFromString.to(dataBean.getSettleTime());
long createTime = TimestampFromString.to(dataBean.getCreateTime());
Platform platform = gamesDataBuildDTO.getPlatform();
String systemCurrency = platform.getOurCurrency(dataBean.getCurrency().toString());
//数据构造
GameBettingDetails gameBettingDetails = GameBettingDetails.builder()
.tenantKey(member.getTenantKey())
//保存我们的币种id
.currencyCode(systemCurrency)
.memberId(member.getId())
.gameCode(game.getGameCode())
.gameType(8) // 体育
.platformCode(GamePlatforms.FBSports.getCode())
.gameId(game.getGameId())
.gameName(game.getGameName())
.gameStatus(compareResult > 0 ? GameStatus.WIN.getCode() : compareResult < 0 ? GameStatus.FAIL.getCode() : GameStatus.FLAT.getCode())
.gameStatusType(1) // 一般下注
.gameCurrencyCode(dataBean.getCurrency().toString())
.account(dataBean.getMerchantUserId())
.wagersId(dataBean.getId())
.wagersTime(createTime)
.betAmount(betAmount)
.payoffTime(payoffTime)
.payoffAmount(originPayoffAmount.abs())
.settlementTime(payoffTime)
.turnover(betAmount)
.orderNo(dataBean.getId())
.settlementStatus(SettlementStatusEnum.COMPLETED.getCode())
.build();
gameBettingDetails.setCreateBy(Constants.SYSTEM);
gameBettingDetails.setCreateTime(DateUtils.getNowDate());
return gameBettingDetails;
}
}

View File

@ -89,11 +89,6 @@ public interface FCClient {
ApiCFBalanceTransferResponseDTO exchangeTransferByAgentId(@JSONBody Map<String, Object> parameters); ApiCFBalanceTransferResponseDTO exchangeTransferByAgentId(@JSONBody Map<String, Object> parameters);
@Post(url = "/GetSingleBill")
ApiCFBalanceTransferStatusResponseDTO exchangeTransferStatus(@JSONBody Map<String, Object> parameters);
/** /**
* *
* *

View File

@ -1,96 +0,0 @@
package com.ff.game.api.fc.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* api cfbalancedto
*
* @author shi
* @date 2025/04/08
*/
@Data
public class ApiCFBalanceTransferStatusResponseDTO {
/**
*
* 0
*/
@JsonProperty("Result")
private int result;
/**
* ID
*/
@JsonProperty("bankID")
private int bankId;
/**
* ID
*/
@JsonProperty("trsID")
private String trsId;
/**
*
*/
@JsonProperty("action")
private String action;
/**
*
*/
@JsonProperty("points")
private BigDecimal points;
/**
*
*/
@JsonProperty("account")
private String account;
/**
*
* 1:
*/
@JsonProperty("status")
private int status;
/**
*
*/
@JsonProperty("beforepoints")
private BigDecimal beforePoints;
/**
*
*/
@JsonProperty("afterpoints")
private BigDecimal afterPoints;
/**
*
*/
@JsonProperty("cdate")
private String createDate;
/**
*
*/
@JsonProperty("bdate")
private String updateDate;
/**
* ID
*/
@JsonProperty("eventID")
private String eventId;
/**
*
*/
@JsonProperty("currency")
private String currency;
}

View File

@ -37,7 +37,7 @@ public class ApiFCGameListResponseDTO {
/** /**
* id * id
*/ */
private String systemGameId; private Long systemGameId;
/** /**
* id * id
*/ */

View File

@ -14,7 +14,6 @@ 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.dg.dto.DGTransactionResponseDTO;
import com.ff.game.api.fc.client.FCClient; import com.ff.game.api.fc.client.FCClient;
import com.ff.game.api.fc.dto.*; import com.ff.game.api.fc.dto.*;
import com.ff.game.api.request.*; import com.ff.game.api.request.*;
@ -259,6 +258,7 @@ public class GamesFCServiceImpl implements IGamesService {
ApiFCGameListResponseDTO.GameDetails gameDetails = integerGameDetailsMap.get(gameIdKey); ApiFCGameListResponseDTO.GameDetails gameDetails = integerGameDetailsMap.get(gameIdKey);
Game game = Game.builder() Game game = Game.builder()
//.platformId(gamePlatform.getId())
.platformCode(GamePlatforms.FC.getCode()) .platformCode(GamePlatforms.FC.getCode())
.gameCode(gameIdKey) .gameCode(gameIdKey)
.build(); .build();
@ -269,28 +269,41 @@ public class GamesFCServiceImpl implements IGamesService {
game.setGameSourceType(String.valueOf(PlatformType.ELECTRONIC.getCode())); game.setGameSourceType(String.valueOf(PlatformType.ELECTRONIC.getCode()));
game.setFreespin(Boolean.FALSE); game.setFreespin(Boolean.FALSE);
game.setDemoStatus(Boolean.TRUE); game.setDemoStatus(Boolean.TRUE);
game.setPlatformCode(GamePlatforms.FC.getCode());
game.setPlatformType(platformType);
game.setSortNo(gameService.selectMaxSortNo(platformType, GamePlatforms.FC.getCode()) + 1); game.setSortNo(gameService.selectMaxSortNo(platformType, GamePlatforms.FC.getCode()) + 1);
game.setGameName(gameDetails.getGameNameOfChinese()); game.setGameName(gameDetails.getGameNameOfChinese());
game.setCreateBy(Constants.SYSTEM); game.setCreateBy(Constants.SYSTEM);
game.setPlatformCode(GamePlatforms.FC.getCode());
game.setPlatformType(platformType);
List<NameInfo> nameInfos = new ArrayList<>(); List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(NameInfo.builder().lang("zh-CN").name(gameDetails.getGameNameOfChinese()).build()); nameInfos.add(NameInfo.builder().lang("zh-CN").name(gameDetails.getGameNameOfChinese()).build());
nameInfos.add(NameInfo.builder().lang("en-US").name(gameDetails.getGameNameOfEnglish()).build()); nameInfos.add(NameInfo.builder().lang("en-US").name(gameDetails.getGameNameOfEnglish()).build());
game.setNameInfo(nameInfos); game.setNameInfo(nameInfos);
game.setGameId(StringUtils.addSuffix(GamePlatforms.FC.getCode(), gameIdKey));
gameService.insertGame(game); gameService.insertGame(game);
} else { } else {
game = games.get(0); game = games.get(0);
List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(NameInfo.builder().lang("zh-CN").name(gameDetails.getGameNameOfChinese()).build());
nameInfos.add(NameInfo.builder().lang("en-US").name(gameDetails.getGameNameOfEnglish()).build());
game.setNameInfo(nameInfos);
gameService.updateGame(game);
} }
gameDetails.setSystemGameId(game.getGameId()); gameDetails.setSystemGameId(game.getId());
/*List<GameName> gameNames = gameNameService.selectGameNameList(GameName.builder().gameId(game.getId()).gameName(gameDetails.getGameNameOfChinese()).build());
if (CollectionUtils.isEmpty(gameNames)) {
gameNameService.insertGameName(GameName.builder()
.gameId(game.getId())
.gameName(gameDetails.getGameNameOfChinese())
.langCode("zh-CN")
.createBy(Constants.SYSTEM)
.build());
}
gameNames = gameNameService.selectGameNameList(GameName.builder().gameId(game.getId()).gameName(gameDetails.getGameNameOfEnglish()).build());
if (CollectionUtils.isEmpty(gameNames)) {
gameNameService.insertGameName(GameName.builder()
.gameId(game.getId())
.gameName(gameDetails.getGameNameOfEnglish())
.langCode("en-US")
.createBy(Constants.SYSTEM)
.build());
}*/
gameDetails.setGameId(gameIdKey); gameDetails.setGameId(gameIdKey);
gameDetailsList.add(gameDetails); gameDetailsList.add(gameDetails);
} }
@ -317,9 +330,36 @@ public class GamesFCServiceImpl implements IGamesService {
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesFCServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesFCServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.FC.getInfo())
// .code(exchangeTransferMoneyRequestDTO.getAgentId())
// .currency(exchangeTransferMoneyRequestDTO.getCurrency())
// .build());
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId()); Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = gameExchangeMoneyService.getTransactionId(GamePlatforms.FC.getInfo(), 30);
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.FC.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
//获取余额 //获取余额
String type = TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType()) ? FCTransferType.TRANSFER_OUT_ALL.getValue() : FCTransferType.TRANSFER_OUT.getValue(); String type = TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType()) ? FCTransferType.TRANSFER_OUT_ALL.getValue() : FCTransferType.TRANSFER_OUT.getValue();
@ -330,7 +370,7 @@ public class GamesFCServiceImpl implements IGamesService {
//获取当前游戏币 //获取当前游戏币
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(exchangeTransferMoneyRequestDTO.getAccount()) .accounts(member.getGameAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId()) .agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey()) .agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()) .currency(exchangeTransferMoneyRequestDTO.getCurrency())
@ -344,7 +384,7 @@ public class GamesFCServiceImpl implements IGamesService {
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("MemberAccount", exchangeTransferMoneyRequestDTO.getAccount()); paramsMap.put("MemberAccount", exchangeTransferMoneyRequestDTO.getAccount());
paramsMap.put("TrsID", exchangeTransferMoneyRequestDTO.getTransactionId()); paramsMap.put("TrsID", transactionId);
paramsMap.put("AllOut", type); paramsMap.put("AllOut", type);
paramsMap.put("Points", amount); paramsMap.put("Points", amount);
paramsMap.putAll(getKeyMap(paramsMap, gamesBaseRequestDTO.getAgentKey(), gamesBaseRequestDTO.getCurrency(), gamesBaseRequestDTO.getAgentId())); paramsMap.putAll(getKeyMap(paramsMap, gamesBaseRequestDTO.getAgentKey(), gamesBaseRequestDTO.getCurrency(), gamesBaseRequestDTO.getAgentId()));
@ -358,60 +398,25 @@ public class GamesFCServiceImpl implements IGamesService {
exchangeMoney.setCoinAfter(transferResponseDTO.getAfterPoint()); exchangeMoney.setCoinAfter(transferResponseDTO.getAfterPoint());
exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore()); exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore());
exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter()); exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter());
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode()); exchangeMoney.setStatus(StatusType.SUCCESS.getValue());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney); gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
} else { } else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
log.error("GamesFCServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{}", transferResponseDTO.getResult()); log.error("GamesFCServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{}", transferResponseDTO.getResult());
throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode()); throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode());
} }
return exchangeMoney.getId(); return exchangeMoney.getId();
} }
/**
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
@Override
public String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO) {
return gameExchangeMoneyService.getTransactionId(GamePlatforms.FC.getInfo(), 30);
}
/** /**
* *
* *
* @param exchangeTransferMoneyRequestDTO dto * @param exchangeTransferMoneyRequestDTO dto
* @return {@link ExchangeTransferStatusResponseDTO } * @return {@link Boolean }
*/ */
@Override @Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesDGServiceImpl [exchangeTransferStatus] 请求参数 {}", exchangeTransferMoneyRequestDTO); throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("TrsID", exchangeTransferMoneyRequestDTO.getOrderId());
paramsMap.putAll(getKeyMap(paramsMap, exchangeTransferMoneyRequestDTO.getAgentKey(), exchangeTransferMoneyRequestDTO.getCurrency(), exchangeTransferMoneyRequestDTO.getAgentId()));
ApiCFBalanceTransferStatusResponseDTO apiCFBalanceTransferStatusResponseDTO = FCClient.exchangeTransferStatus(paramsMap);
Integer status = StatusType.IN_PROGRESS.getValue();
if (this.getIsSuccess(apiCFBalanceTransferStatusResponseDTO.getResult())) {
status = StatusType.SUCCESS.getValue();
} else {
status = StatusType.FAILURE.getValue();
}
return ExchangeTransferStatusResponseDTO.builder()
.statusType(status)
.balance(apiCFBalanceTransferStatusResponseDTO.getPoints())
.coinBefore(apiCFBalanceTransferStatusResponseDTO.getBeforePoints())
.coinAfter(apiCFBalanceTransferStatusResponseDTO.getAfterPoints())
.build();
} }
@ -425,8 +430,14 @@ public class GamesFCServiceImpl implements IGamesService {
@Override @Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
// List<GameSecretKeyCurrencyDTO> gameSecretKeyCurrencies = gameSecretKeyCurrencyService
// .findByGameSecretKeyCurrencyDTOList(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.FC.getInfo())
// .build());
Platform platform = betRecordByTimeDTO.getVendor(); Platform platform = betRecordByTimeDTO.getVendor();
//for (KeyInfo keyInfo : platform.getKeyInfo()) {
// for (GameSecretKeyCurrency gameSecretKeyCurrency : gameSecretKeyCurrencies) {
String startTime = DateUtils.convertTimeZone(betRecordByTimeDTO.getStartTime(), "America/New_York", DateUtils.YYYY_MM_DD_HH_MM_SS); String startTime = DateUtils.convertTimeZone(betRecordByTimeDTO.getStartTime(), "America/New_York", DateUtils.YYYY_MM_DD_HH_MM_SS);
String endTime = DateUtils.convertTimeZone(betRecordByTimeDTO.getEndTime(), "America/New_York", DateUtils.YYYY_MM_DD_HH_MM_SS); String endTime = DateUtils.convertTimeZone(betRecordByTimeDTO.getEndTime(), "America/New_York", DateUtils.YYYY_MM_DD_HH_MM_SS);
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
@ -437,6 +448,7 @@ public class GamesFCServiceImpl implements IGamesService {
String targetCurrency = platform.getCurrencyInfo().get(currency); String targetCurrency = platform.getCurrencyInfo().get(currency);
if (StringUtils.isEmpty(targetCurrency)) { if (StringUtils.isEmpty(targetCurrency)) {
log.error("获取不到币种,platformCode:{},{}->{}", platform.getPlatformCode(), currency, targetCurrency); log.error("获取不到币种,platformCode:{},{}->{}", platform.getPlatformCode(), currency, targetCurrency);
//continue;
return Boolean.FALSE; return Boolean.FALSE;
} }
@ -448,6 +460,7 @@ public class GamesFCServiceImpl implements IGamesService {
//数据组装 //数据组装
this.batchInsert(betRecordByTime, currency, targetCurrency); this.batchInsert(betRecordByTime, currency, targetCurrency);
} }
//}
return Boolean.TRUE; return Boolean.TRUE;
} }
@ -463,7 +476,7 @@ public class GamesFCServiceImpl implements IGamesService {
Platform platform = betRecordByTimeDTO.getVendor(); Platform platform = betRecordByTimeDTO.getVendor();
for (KeyInfo keyInfo : platform.getKeyInfo()) { for (KeyInfo keyInfo : platform.getKeyInfo()) {
// for (GameSecretKeyCurrency gameSecretKeyCurrency : gameSecretKeyCurrencies) {
//必须两个小时之前的数据 //必须两个小时之前的数据
long startTimeLong = DateUtils.addOrSubtractMinutes(betRecordByTimeDTO.getStartTime(), -120); long startTimeLong = DateUtils.addOrSubtractMinutes(betRecordByTimeDTO.getStartTime(), -120);
long endTimeLong = DateUtils.addOrSubtractMinutes(betRecordByTimeDTO.getEndTime(), -120); long endTimeLong = DateUtils.addOrSubtractMinutes(betRecordByTimeDTO.getEndTime(), -120);

View File

@ -24,7 +24,7 @@ public class MyJILIAddressSource implements AddressSource {
@Override @Override
public ForestAddress getAddress(ForestRequest request) { public ForestAddress getAddress(ForestRequest request) {
String apiBaseUrl = platformService.get(GamePlatforms.JILI.getCode()) String apiBaseUrl = platformService.get(GamePlatforms.FC.getCode())
.getUrlInfo().getUrl(); .getUrlInfo().getUrl();
return new ForestAddress("https", apiBaseUrl, 443, "api1"); return new ForestAddress("https", apiBaseUrl, 443, "api1");
} }

View File

@ -63,22 +63,6 @@ public interface JILIClient {
) )
JILIExchangeMoneyResponseDTO exchangeTransferByAgentId(@Var("parameters") String parameters,@Body("AgentId") String agentId); JILIExchangeMoneyResponseDTO exchangeTransferByAgentId(@Var("parameters") String parameters,@Body("AgentId") String agentId);
/**
* id
*
* @param parameters
* @param agentId id
* @return {@link JILITransferStatusResponseDTO }
*/
@Post(
url = "/CheckTransferByTransactionId?${parameters}",
headers = {
"Content-type: application/x-www-form-urlencoded"
}
)
JILITransferStatusResponseDTO checkTransferByTransactionId(@Var("parameters") String parameters,@Body("AgentId") String agentId);
/** /**
* *
* *

View File

@ -22,7 +22,7 @@ public class JILIGamesDataDTO {
/** /**
*id *id
*/ */
private String systemGameId; private Long systemGameId;
/** /**
* *

View File

@ -1,78 +0,0 @@
package com.ff.game.api.jili.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* jilitransfer
*
* @author shi
* @date 2025/04/08
*/
@Data
public class JILITransferStatusResponseDTO {
/**
* 0
*/
@JsonProperty("ErrorCode")
private int errorCode;
/**
*
*/
@JsonProperty("Message")
private String message;
/**
*
*/
@JsonProperty("Data")
private TransferData data;
/**
*
*/
@Data
public static class TransferData {
/**
*
*/
@JsonProperty("Account")
private String account;
/**
* ID
*/
@JsonProperty("TransactionId")
private String transactionId;
/**
* ISO 86012023-03-13T01:13:59-04:00
*/
@JsonProperty("TransferTime")
private String transferTime;
/**
*
*/
@JsonProperty("Amount")
private BigDecimal amount;
/**
* 1
*/
@JsonProperty("Status")
private int status;
/**
* 1 2
*/
@JsonProperty("TransferType")
private int transferType;
}
}

View File

@ -15,7 +15,6 @@ import com.ff.base.utils.sign.Md5Utils;
import com.ff.base.utils.uuid.IdUtils; import com.ff.base.utils.uuid.IdUtils;
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.ApiCFBalanceTransferStatusResponseDTO;
import com.ff.game.api.jili.client.JILIClient; import com.ff.game.api.jili.client.JILIClient;
import com.ff.game.api.jili.dto.*; import com.ff.game.api.jili.dto.*;
import com.ff.game.api.request.*; import com.ff.game.api.request.*;
@ -227,8 +226,23 @@ public class GamesJILIServiceImpl implements IGamesService {
if (this.getIsSuccess(jiliGames.getErrorCode())) { if (this.getIsSuccess(jiliGames.getErrorCode())) {
for (JILIGamesDataDTO gamesDataDTO : jiliGames.getData()) { for (JILIGamesDataDTO gamesDataDTO : jiliGames.getData()) {
/*GamePlatform gamePlatform = GamePlatform.builder()
.platformType(JILIGameType.findSystemByCode(gamesDataDTO.getGameCategoryId()))
.platformCode(GamePlatforms.JILI.getInfo())
.build();
List<GamePlatform> gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform);
//没有此平台就新增一个平台
if (CollectionUtils.isEmpty(gamePlatforms)) {
gamePlatform.setPlatformName(GamePlatforms.JILI.getInfo() + JILIGameType.findInfoByCode(gamesDataDTO.getGameCategoryId()));
gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1);
gamePlatform.setCreateBy(Constants.SYSTEM);
gamePlatformService.insertGamePlatform(gamePlatform);
} else {
gamePlatform = gamePlatforms.get(0);
}*/
Integer platformType = JILIGameType.findSystemByCode(gamesDataDTO.getGameCategoryId()); Integer platformType = JILIGameType.findSystemByCode(gamesDataDTO.getGameCategoryId());
Game game = Game.builder() Game game = Game.builder()
//.platformId(gamePlatform.getId())
.platformCode(GamePlatforms.JILI.getCode()) .platformCode(GamePlatforms.JILI.getCode())
.platformType(platformType) .platformType(platformType)
.gameCode(String.valueOf(gamesDataDTO.getGameId())) .gameCode(String.valueOf(gamesDataDTO.getGameId()))
@ -243,7 +257,7 @@ public class GamesJILIServiceImpl implements IGamesService {
game.setCreateBy(Constants.SYSTEM); game.setCreateBy(Constants.SYSTEM);
game.setPlatformType(platformType); game.setPlatformType(platformType);
game.setPlatformCode(GamePlatforms.JILI.getCode()); game.setPlatformCode(GamePlatforms.JILI.getCode());
game.setGameId(StringUtils.addSuffix(GamePlatforms.JILI.getCode(), gamesDataDTO.getGameId()));
List<NameInfo> nameInfos = new ArrayList<>(); List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(new NameInfo(gamesDataDTO.getName().getZhCN(), "zh-CN")); nameInfos.add(new NameInfo(gamesDataDTO.getName().getZhCN(), "zh-CN"));
nameInfos.add(new NameInfo(gamesDataDTO.getName().getEnUS(), "en-US")); nameInfos.add(new NameInfo(gamesDataDTO.getName().getEnUS(), "en-US"));
@ -252,13 +266,29 @@ public class GamesJILIServiceImpl implements IGamesService {
gameService.insertGame(game); gameService.insertGame(game);
} else { } else {
game = games.get(0); game = games.get(0);
List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(new NameInfo(gamesDataDTO.getName().getZhCN(), "zh-CN"));
nameInfos.add(new NameInfo(gamesDataDTO.getName().getEnUS(), "en-US"));
game.setNameInfo(nameInfos);
gameService.updateGame(game);
} }
gamesDataDTO.setSystemGameId(game.getGameId()); 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.getName().getEnUS())
.langCode("en-US")
.createBy(Constants.SYSTEM)
.build());
}*/
} }
@ -274,17 +304,6 @@ public class GamesJILIServiceImpl implements IGamesService {
return CacheConstants.JILI_GAMES; return CacheConstants.JILI_GAMES;
} }
/**
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
@Override
public String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO) {
return GamePlatforms.JILI.getInfo() + IdUtils.simpleUUID();
}
/** /**
* id * id
* *
@ -294,14 +313,38 @@ public class GamesJILIServiceImpl implements IGamesService {
@Override @Override
@Transactional @Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .code(exchangeTransferMoneyRequestDTO.getAgentId())
// .currency(exchangeTransferMoneyRequestDTO.getCurrency()).build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId()); String transactionId = GamePlatforms.JILI.getInfo() + 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(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.JILI.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
//接口限制限制50字符
exchangeMoney.setTransactionId(transactionId);
String query = "Account=" + exchangeTransferMoneyRequestDTO.getAccount() String query = "Account=" + exchangeTransferMoneyRequestDTO.getAccount()
+ "&TransactionId=" + exchangeMoney.getTransactionId() + "&TransactionId=" + exchangeMoney.getTransactionId()
+ "&Amount=" + exchangeTransferMoneyRequestDTO.getAmount() + "&Amount=" + exchangeTransferMoneyRequestDTO.getAmount()
@ -328,14 +371,10 @@ public class GamesJILIServiceImpl implements IGamesService {
exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter()); exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter());
exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore()); exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore());
exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter()); exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter());
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode()); exchangeMoney.setStatus(exchangeMoneyResponseData.getStatus());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode()); gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else { } else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
throw new BaseException(exchangeMoneyResponse.getMessage()); throw new BaseException(exchangeMoneyResponse.getMessage());
} }
@ -350,32 +389,8 @@ public class GamesJILIServiceImpl implements IGamesService {
* @return {@link Boolean } * @return {@link Boolean }
*/ */
@Override @Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesDGServiceImpl [exchangeTransferStatus] 请求参数 {}", exchangeTransferMoneyRequestDTO); return Boolean.TRUE;
String query = "TransactionId=" + exchangeTransferMoneyRequestDTO.getOrderId()
+ "&AgentId=" + exchangeTransferMoneyRequestDTO.getAgentId();
exchangeTransferMoneyRequestDTO.setQuery(query);
String key = this.getKey(exchangeTransferMoneyRequestDTO);
JILITransferStatusResponseDTO jiliTransferStatusResponseDTO = jiliClient.checkTransferByTransactionId(query + "&Key=" + key, exchangeTransferMoneyRequestDTO.getAgentId());
Integer status = StatusType.IN_PROGRESS.getValue();
if (this.getIsSuccess(jiliTransferStatusResponseDTO.getErrorCode())) {
status = StatusType.SUCCESS.getValue();
} else {
status = StatusType.FAILURE.getValue();
}
JILITransferStatusResponseDTO.TransferData data = jiliTransferStatusResponseDTO.getData();
ExchangeTransferStatusResponseDTO statusResponseDTO = ExchangeTransferStatusResponseDTO.builder()
.statusType(status)
.build();
if (!ObjectUtils.isEmpty(data)) {
statusResponseDTO.setBalance(data.getAmount());
}
return statusResponseDTO;
} }
@ -437,45 +452,7 @@ public class GamesJILIServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
String startTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getStartTime())); return null;
String endTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getEndTime()));
//请求参数
String query = "StartTime=" + startTime + "&EndTime=" + endTime + "&Page=" + betRecordByTimeDTO.getPage() + "&PageLimit=" + betRecordByTimeDTO.getPageLimit() + "&AgentId=" + betRecordByTimeDTO.getAgentId();
log.info("GamesJILIServiceImpl [getBetRecordByHistoryTime] 请求参数 {}", query);
betRecordByTimeDTO.setQuery(query);
//获取key
String key = this.getKey(betRecordByTimeDTO);
JILIBetRecordResponseDTO betRecordJILIResponse = jiliClient.getBetRecordByTime(query + "&Key=" + key, betRecordByTimeDTO.getAgentId());
//判断是否获取成功
if (this.getIsSuccess(betRecordJILIResponse.getErrorCode())) {
//数据插入
this.batchInsert(betRecordJILIResponse, betRecordByTimeDTO);
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 [getBetRecordByHistoryTime] 请求参数 {}", query);
betRecordByTimeDTO.setQuery(query);
key = this.getKey(betRecordByTimeDTO);
betRecordJILIResponse = jiliClient.getBetRecordByTime(query + "&Key=" + key, betRecordByTimeDTO.getAgentId());
dataBean = betRecordJILIResponse.getData();
if (this.getIsSuccess(betRecordJILIResponse.getErrorCode())) {
//数据插入
this.batchInsert(betRecordJILIResponse, betRecordByTimeDTO);
} else {
log.error("GameBettingDataJILIServiceImpl [getBetRecordByHistoryTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getErrorCode(), betRecordJILIResponse.getMessage());
}
}
} else {
log.error("GameBettingDataJILIServiceImpl [getBetRecordByHistoryTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getErrorCode(), betRecordJILIResponse.getMessage());
return Boolean.FALSE;
}
return Boolean.TRUE;
} }
@ -490,6 +467,9 @@ public class GamesJILIServiceImpl implements IGamesService {
String freeSpinValidity = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getFreeSpinValidity())); String freeSpinValidity = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getFreeSpinValidity()));
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .code(createFreeSpinRequest.getAgentId())
// .currency(createFreeSpinRequest.getCurrency()).build());
List<Long> gameIds = createFreeSpinRequest.getGameIds(); List<Long> gameIds = createFreeSpinRequest.getGameIds();
GameUniqueDTO gameUniqueDTO = new GameUniqueDTO(); GameUniqueDTO gameUniqueDTO = new GameUniqueDTO();
@ -698,6 +678,7 @@ public class GamesJILIServiceImpl implements IGamesService {
//请求参数 //请求参数
String query = "ReferenceId=" + cancelFreeSpinRequestDTO.getReferenceId() String query = "ReferenceId=" + cancelFreeSpinRequestDTO.getReferenceId()
+ "&AgentId=" + cancelFreeSpinRequestDTO.getAgentId(); + "&AgentId=" + cancelFreeSpinRequestDTO.getAgentId();
;
log.info("GamesJILIServiceImpl [cancelFreeSpin] 请求参数 {}", query); log.info("GamesJILIServiceImpl [cancelFreeSpin] 请求参数 {}", query);
cancelFreeSpinRequestDTO.setQuery(query); cancelFreeSpinRequestDTO.setQuery(query);
//获取key //获取key
@ -736,7 +717,7 @@ public class GamesJILIServiceImpl implements IGamesService {
* @param betRecordJILIResponse jiliresponse * @param betRecordJILIResponse jiliresponse
* @return {@link Integer } * @return {@link Integer }
*/ */
private synchronized void batchInsert(JILIBetRecordResponseDTO betRecordJILIResponse, BetRecordByTimeDTO betRecordByTimeDTO) { private void batchInsert(JILIBetRecordResponseDTO betRecordJILIResponse, BetRecordByTimeDTO betRecordByTimeDTO) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>(); List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<String> wagersIds = new ArrayList<>(); List<String> wagersIds = new ArrayList<>();
//数据组装 //数据组装
@ -780,6 +761,10 @@ public class GamesJILIServiceImpl implements IGamesService {
//转化类 //转化类
JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO = (JILIBetRecordDataResponseDTO) gamesDataBuildDTO.getData(); JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO = (JILIBetRecordDataResponseDTO) gamesDataBuildDTO.getData();
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .code(jiliBetRecordDataResponseDTO.getAgentId())
// .platformCode(GamePlatforms.JILI.getInfo()).build());
Member member = memberService.selectMemberByGameAccount(jiliBetRecordDataResponseDTO.getAccount()); Member member = memberService.selectMemberByGameAccount(jiliBetRecordDataResponseDTO.getAccount());
if (ObjectUtils.isEmpty(member)) { if (ObjectUtils.isEmpty(member)) {
@ -804,7 +789,7 @@ public class GamesJILIServiceImpl implements IGamesService {
.gameCode(jiliBetRecordDataResponseDTO.getGameId()) .gameCode(jiliBetRecordDataResponseDTO.getGameId())
.gameType(JILIGameType.findSystemByCode(jiliBetRecordDataResponseDTO.getGameCategoryId())) .gameType(JILIGameType.findSystemByCode(jiliBetRecordDataResponseDTO.getGameCategoryId()))
.platformCode(GamePlatforms.JILI.getInfo()) .platformCode(GamePlatforms.JILI.getInfo())
.gameId(/*gamesDataDTO.getSystemGameId()*/gamesDataDTO.getSystemGameId()) .gameId(gamesDataDTO.getSystemGameId())
.gameName(gamesDataDTO.getName().getZhCN()) .gameName(gamesDataDTO.getName().getZhCN())
.gameStatus(jiliBetRecordDataResponseDTO.getStatus()) .gameStatus(jiliBetRecordDataResponseDTO.getStatus())
.gameStatusType(jiliBetRecordDataResponseDTO.getType()) .gameStatusType(jiliBetRecordDataResponseDTO.getType())

View File

@ -2,11 +2,13 @@ package com.ff.game.api.km.client;
import com.dtflys.forest.annotation.*; import com.dtflys.forest.annotation.*;
import com.ff.game.api.dg.dto.DGBetRecordResponseDTO;
import com.ff.game.api.dg.dto.DGResponse; import com.ff.game.api.dg.dto.DGResponse;
import com.ff.game.api.fc.dto.ApiCFBalanceTransferStatusResponseDTO; import com.ff.game.api.dg.dto.DGUserListResponseDTO;
import com.ff.game.api.km.address.MyKMAddressSource; import com.ff.game.api.km.address.MyKMAddressSource;
import com.ff.game.api.km.dto.*; import com.ff.game.api.km.dto.*;
import com.ff.game.api.success.MySuccessCondition; import com.ff.game.api.km.success.MyKMSuccessCondition;
import com.ff.game.api.xk.dto.XKBetRecordResponseDTO;
import java.util.Map; import java.util.Map;
@ -17,7 +19,7 @@ import java.util.Map;
* @date 2025/02/10 * @date 2025/02/10
*/ */
@Address(source = MyKMAddressSource.class) @Address(source = MyKMAddressSource.class)
@Success(condition = MySuccessCondition.class) @Success(condition = MyKMSuccessCondition.class)
public interface KMClient { public interface KMClient {
/** /**
* *
@ -79,16 +81,6 @@ public interface KMClient {
@Get(url ="/v2/history/bets?{params}") @Get(url ="/v2/history/bets?{params}")
KMBetRecordResponse getBetRecordByTime(@Var("params")String params, @Header Map<String, Object> header); KMBetRecordResponse getBetRecordByTime(@Var("params")String params, @Header Map<String, Object> header);
/**
*
*
* @param params
* @param parameters
* @return {@link KMBalanceTransferStatusResponseDTO }
*/
@Post(url = "/history/transfers/{params}")
KMBalanceTransferStatusResponseDTO exchangeTransferStatus(@Var("params")String params,@JSONBody Map<String, Object> parameters);
/** /**
* *

View File

@ -1,77 +0,0 @@
package com.ff.game.api.km.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* km
*
* @author shi
* @date 2025/04/08
*/
@Data
public class KMBalanceTransferStatusResponseDTO {
/**
*
*/
@JsonProperty("err")
private Integer errorCode;
/**
*
*/
@JsonProperty("errdesc")
private String errorDescription;
/**
* ID
*/
@JsonProperty("txid")
private String txid;
/**
* ISO 86012017-12-12T12:11:16+08:00
*/
@JsonProperty("timestamp")
private String timestamp;
/**
* ID
*/
@JsonProperty("userid")
private String userid;
/**
*
*/
@JsonProperty("username")
private String username;
/**
* 1
*/
@JsonProperty("playertype")
private int playertype;
/**
*
*/
@JsonProperty("amt")
private BigDecimal amt;
/**
*
*/
@JsonProperty("postbal")
private BigDecimal postbal;
/**
* ISO 4217 THB
*/
@JsonProperty("cur")
private String cur;
}

View File

@ -91,7 +91,7 @@ public class KMGameResponse {
/** /**
* id * id
*/ */
private String systemGameId; private Long systemGameId;
/** /**
* *

View File

@ -15,8 +15,6 @@ import com.ff.base.utils.ip.IpUtils;
import com.ff.base.utils.uuid.IdUtils; import com.ff.base.utils.uuid.IdUtils;
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.ApiCFBalanceTransferStatusResponseDTO;
import com.ff.game.api.jili.dto.JILITransferStatusResponseDTO;
import com.ff.game.api.km.client.KMClient; import com.ff.game.api.km.client.KMClient;
import com.ff.game.api.km.dto.*; import com.ff.game.api.km.dto.*;
import com.ff.game.api.request.*; import com.ff.game.api.request.*;
@ -80,6 +78,21 @@ public class GamesKMServiceImpl implements IGamesService {
private IGameBettingDetailsService gameBettingDetailsService; private IGameBettingDetailsService gameBettingDetailsService;
/**
* id
*/
private static final Long GAME_ID = 1904452832756003817L;
/**
* ID
*/
private static final Long PLATFORM_ID = 1904411420157108325L;
/**
* id
*/
private static final Long GAME_NAME_ID = 1904452832756002317L;
/** /**
* *
* *
@ -155,7 +168,11 @@ public class GamesKMServiceImpl implements IGamesService {
public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) { public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) {
log.info("GamesDGServiceImpl [getMemberInfo] 请求参数 {}", memberInfoRequestDTO); log.info("GamesDGServiceImpl [getMemberInfo] 请求参数 {}", memberInfoRequestDTO);
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
// Member member = memberService.selectMemberByGameAccount(memberInfoRequestDTO.getAccounts());
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.KM.getInfo())
// .currency(member.getCurrencyCode())
// .build());
paramsMap.put("userid", memberInfoRequestDTO.getAccounts()); paramsMap.put("userid", memberInfoRequestDTO.getAccounts());
paramsMap.put("cur", memberInfoRequestDTO.getCurrency()); paramsMap.put("cur", memberInfoRequestDTO.getCurrency());
@ -179,7 +196,11 @@ public class GamesKMServiceImpl implements IGamesService {
log.info("GamesKMServiceImpl [loginWithoutRedirect] 请求参数 {}", gamesLogin); log.info("GamesKMServiceImpl [loginWithoutRedirect] 请求参数 {}", gamesLogin);
String kmUserToken = redisCache.getCacheObject(CacheConstants.KM_USER_TOKEN + gamesLogin.getAccount()); String kmUserToken = redisCache.getCacheObject(CacheConstants.KM_USER_TOKEN + gamesLogin.getAccount());
if (StringUtils.isEmpty(kmUserToken)) { if (StringUtils.isEmpty(kmUserToken)) {
// Member member = memberService.selectMemberByGameAccount(gamesLogin.getAccount());
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.KM.getInfo())
// .currency(member.getCurrencyCode())
// .build());
CreateMemberRequestDTO gamesBaseRequestDTO = CreateMemberRequestDTO.builder() CreateMemberRequestDTO gamesBaseRequestDTO = CreateMemberRequestDTO.builder()
.account(gamesLogin.getAccount()) .account(gamesLogin.getAccount())
@ -192,6 +213,7 @@ public class GamesKMServiceImpl implements IGamesService {
} }
String loginUrl = platformService.get(GamePlatforms.KM.getCode()).getUrlInfo().getLoginUrl(); String loginUrl = platformService.get(GamePlatforms.KM.getCode()).getUrlInfo().getLoginUrl();
//String selectConfigByKey = configService.selectConfigByKey(Constants.KM_API_BASE_LOGIN_URL);
return loginUrl + "/gamelauncher?gpcode=" + gamesLogin.getGameType() return loginUrl + "/gamelauncher?gpcode=" + gamesLogin.getGameType()
+ "&gcode=" + gamesLogin.getGameId() + "&gcode=" + gamesLogin.getGameId()
@ -247,9 +269,23 @@ public class GamesKMServiceImpl implements IGamesService {
.anyMatch(pc -> pc.getCode().equals(mobile.getCode()))) .anyMatch(pc -> pc.getCode().equals(mobile.getCode())))
.collect(Collectors.toList()); .collect(Collectors.toList());
for (KMGameResponse.Game game : games) { for (KMGameResponse.Game game : games) {
// GamePlatform gamePlatform = GamePlatform.builder()
// .platformType(KMGameType.findSystemByCode(game.getProviderCode()))
// .platformCode(GamePlatforms.KM.getCode())
// .build();
/*List<GamePlatform> gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform);
//没有此平台就新增一个平台
if (CollectionUtils.isEmpty(gamePlatforms)) {
gamePlatform.setPlatformName(GamePlatforms.KM.getInfo() + KMGameType.findInfoByCode(game.getProviderCode()));
gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1);
gamePlatform.setCreateBy(Constants.SYSTEM);
gamePlatformService.insertGamePlatform(gamePlatform);
} else {
gamePlatform = gamePlatforms.get(0);
}*/
Integer platformType = KMGameType.findSystemByCode(game.getProviderCode()); Integer platformType = KMGameType.findSystemByCode(game.getProviderCode());
Game gameOne = Game.builder() Game gameOne = Game.builder()
//.platformId(gamePlatform.getId())
.platformCode(GamePlatforms.KM.getCode()) .platformCode(GamePlatforms.KM.getCode())
.platformType(platformType) .platformType(platformType)
.gameCode(game.getCode()) .gameCode(game.getCode())
@ -276,8 +312,23 @@ public class GamesKMServiceImpl implements IGamesService {
*/ */
private List<KMGameResponse.Game> gameList(KMGameResponse gameList, Integer ingress) { private List<KMGameResponse.Game> gameList(KMGameResponse gameList, Integer ingress) {
for (KMGameResponse.Game gamesDataDTO : gameList.getGames()) { for (KMGameResponse.Game gamesDataDTO : gameList.getGames()) {
// GamePlatform gamePlatform = GamePlatform.builder()
// .platformType(KMGameType.findSystemByCode(gamesDataDTO.getProviderCode()))
// .platformCode(GamePlatforms.KM.getCode())
// .build();
/*List<GamePlatform> gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform);
//没有此平台就新增一个平台
if (CollectionUtils.isEmpty(gamePlatforms)) {
gamePlatform.setPlatformName(GamePlatforms.KM.getInfo() + KMGameType.findInfoByCode(gamesDataDTO.getProviderCode()));
gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1);
gamePlatform.setCreateBy(Constants.SYSTEM);
gamePlatformService.insertGamePlatform(gamePlatform);
} else {
gamePlatform = gamePlatforms.get(0);
}*/
Integer platformType = KMGameType.findSystemByCode(gamesDataDTO.getProviderCode()); Integer platformType = KMGameType.findSystemByCode(gamesDataDTO.getProviderCode());
Game game = Game.builder() Game game = Game.builder()
//.platformId(gamePlatform.getId())
.platformCode(GamePlatforms.KM.getCode()) .platformCode(GamePlatforms.KM.getCode())
.platformType(platformType) .platformType(platformType)
.gameCode(gamesDataDTO.getCode()) .gameCode(gamesDataDTO.getCode())
@ -294,37 +345,28 @@ public class GamesKMServiceImpl implements IGamesService {
game.setIngress(ingress); game.setIngress(ingress);
game.setPlatformCode(GamePlatforms.KM.getCode()); game.setPlatformCode(GamePlatforms.KM.getCode());
game.setPlatformType(platformType); game.setPlatformType(platformType);
game.setGameId(StringUtils.addSuffix(GamePlatforms.KM.getCode(), gamesDataDTO.getCode()));
List<NameInfo> nameInfos = new ArrayList<>(); List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(new NameInfo(gamesDataDTO.getName(), "zh-CN")); nameInfos.add(new NameInfo(gamesDataDTO.getName(), "zh-CN"));
game.setNameInfo(nameInfos); game.setNameInfo(nameInfos);
gameService.insertGame(game); gameService.insertGame(game);
} else { } else {
game = games.get(0); game = games.get(0);
List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(new NameInfo(gamesDataDTO.getName(), "zh-CN"));
game.setNameInfo(nameInfos);
gameService.updateGame(game);
} }
gamesDataDTO.setSystemGameId(game.getGameId()); 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());
// }
} }
return gameList.getGames(); return gameList.getGames();
} }
/**
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
@Override
public String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO) {
return GamePlatforms.KM.getInfo() + IdUtils.simpleUUID();
}
/** /**
* id * id
* *
@ -335,19 +377,41 @@ public class GamesKMServiceImpl implements IGamesService {
@Transactional @Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesKMServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesKMServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.KM.getInfo())
// .currency(exchangeTransferMoneyRequestDTO.getCurrency())
// .build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = GamePlatforms.KM.getInfo() + IdUtils.simpleUUID();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId()); //获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.KM.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount(); BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount();
if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) { if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
// 获取第三方钱包余额 // 获取第三方钱包余额
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(exchangeTransferMoneyRequestDTO.getAccount()) .accounts(member.getGameAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId()) .agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()) .currency(exchangeTransferMoneyRequestDTO.getCurrency())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey()) .agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
@ -360,7 +424,7 @@ public class GamesKMServiceImpl implements IGamesService {
params.put("userid", exchangeTransferMoneyRequestDTO.getAccount()); params.put("userid", exchangeTransferMoneyRequestDTO.getAccount());
params.put("amt", amount); params.put("amt", amount);
params.put("cur", exchangeTransferMoneyRequestDTO.getCurrency()); params.put("cur", exchangeTransferMoneyRequestDTO.getCurrency());
params.put("txid", exchangeTransferMoneyRequestDTO.getTransactionId()); params.put("txid", transactionId);
Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO);
KMTransactionResponse kmTransactionResponse; KMTransactionResponse kmTransactionResponse;
@ -379,13 +443,9 @@ public class GamesKMServiceImpl implements IGamesService {
exchangeMoney.setCoinAfter(kmTransactionResponse.getBalance()); exchangeMoney.setCoinAfter(kmTransactionResponse.getBalance());
exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore()); exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore());
exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter()); exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter());
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode()); exchangeMoney.setStatus(StatusType.SUCCESS.getValue());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode()); gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else { } else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
log.error("GamesDGServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", kmTransactionResponse.getErrorCode(), kmTransactionResponse.getErrorDescription()); log.error("GamesDGServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", kmTransactionResponse.getErrorCode(), kmTransactionResponse.getErrorDescription());
throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode()); throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode());
} }
@ -400,25 +460,8 @@ public class GamesKMServiceImpl implements IGamesService {
* @return {@link Boolean } * @return {@link Boolean }
*/ */
@Override @Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesKMServiceImpl [exchangeTransferStatus] 请求参数 {}", exchangeTransferMoneyRequestDTO); return Boolean.TRUE;
Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO);
KMBalanceTransferStatusResponseDTO kmBalanceTransferStatusResponseDTO = KMClient.exchangeTransferStatus(exchangeTransferMoneyRequestDTO.getOrderId(), headerMap);
Integer status = StatusType.IN_PROGRESS.getValue();
if (ObjectUtils.isEmpty(kmBalanceTransferStatusResponseDTO.getErrorCode()) || this.getIsSuccess(kmBalanceTransferStatusResponseDTO.getErrorCode())) {
status = StatusType.SUCCESS.getValue();
} else {
status = StatusType.FAILURE.getValue();
}
return ExchangeTransferStatusResponseDTO.builder()
.statusType(status)
.balance(kmBalanceTransferStatusResponseDTO.getAmt())
.coinBefore(NumberUtil.sub(kmBalanceTransferStatusResponseDTO.getAmt(), kmBalanceTransferStatusResponseDTO.getPostbal()).abs())
.coinAfter(kmBalanceTransferStatusResponseDTO.getPostbal())
.build();
} }
@ -471,35 +514,7 @@ public class GamesKMServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
return null;
log.info("GamesKMServiceImpl [getBetRecordByHistoryTime] 请求参数 {}", betRecordByTimeDTO);
Map<String, Object> key = this.getKey(betRecordByTimeDTO);
String startTime = null;
String endTime = null;
try {
startTime = URLEncoder.encode(DateUtils.convertTimestampToFormattedDate(betRecordByTimeDTO.getStartTime(), DateUtils.ISO_8601_FORMAT, "GMT+8") + "+08:00", "UTF-8");
endTime = URLEncoder.encode(DateUtils.convertTimestampToFormattedDate(betRecordByTimeDTO.getEndTime(), DateUtils.ISO_8601_FORMAT, "GMT+8") + "+08:00", "UTF-8");
} catch (Exception e) {
throw new BaseException(e.getMessage());
}
Map<String, Object> params = new LinkedHashMap<>();
params.put("startdate", startTime);
params.put("enddate", endTime);
params.put("includetestplayers", Boolean.TRUE);
params.put("issettled", Boolean.TRUE);
KMBetRecordResponse betRecordByTime = KMClient.getBetRecordByTime(JsonUtil.mapToQueryString(params), key);
if (ObjectUtils.isEmpty(betRecordByTime.getErrorCode()) || this.getIsSuccess(betRecordByTime.getErrorCode())) {
this.batchInsert(betRecordByTime, betRecordByTimeDTO);
return Boolean.TRUE;
} else {
log.error("GamesKMServiceImpl [getBetRecordByHistoryTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordByTime.getErrorCode(), betRecordByTime.getErrorDescription());
throw new BaseException(betRecordByTime.getErrorDescription());
}
} }
/** /**
@ -646,7 +661,11 @@ public class GamesKMServiceImpl implements IGamesService {
public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) { public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) {
//转化类 //转化类
KMBetRecordResponse.Bet resultBean = (KMBetRecordResponse.Bet) gamesDataBuildDTO.getData(); KMBetRecordResponse.Bet resultBean = (KMBetRecordResponse.Bet) gamesDataBuildDTO.getData();
//
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.KM.getInfo())
// .currency(resultBean.getCurrency())
// .build());
Member member = memberService.selectMemberByGameAccount(resultBean.getUserId()); Member member = memberService.selectMemberByGameAccount(resultBean.getUserId());
@ -659,6 +678,7 @@ public class GamesKMServiceImpl implements IGamesService {
e -> e, e -> e,
(existing, replacement) -> existing (existing, replacement) -> existing
)); ));
;
KMGameResponse.Game gamesDataDTO = dataDTOMap.get(resultBean.getGCode()); KMGameResponse.Game gamesDataDTO = dataDTOMap.get(resultBean.getGCode());
//输赢状态 //输赢状态
@ -682,7 +702,7 @@ public class GamesKMServiceImpl implements IGamesService {
.gameCode(gamesDataDTO.getCode()) .gameCode(gamesDataDTO.getCode())
.gameType(PlatformType.CARD_GAME.getCode()) .gameType(PlatformType.CARD_GAME.getCode())
.platformCode(GamePlatforms.KM.getCode()) .platformCode(GamePlatforms.KM.getCode())
.gameId(gamesDataDTO.getSystemGameId()) .gameId(GAME_ID)
.gameName(gamesDataDTO.getName()) .gameName(gamesDataDTO.getName())
.gameStatus(gameStatus) .gameStatus(gameStatus)
.gameStatusType(1) .gameStatusType(1)

View File

@ -1,4 +1,4 @@
package com.ff.game.api.success; package com.ff.game.api.km.success;
import com.dtflys.forest.callback.SuccessWhen; import com.dtflys.forest.callback.SuccessWhen;
@ -11,7 +11,7 @@ import com.dtflys.forest.http.ForestResponse;
* @author shi * @author shi
* @date 2025/04/02 * @date 2025/04/02
*/ */
public class MySuccessCondition implements SuccessWhen { public class MyKMSuccessCondition implements SuccessWhen {
/** /**
* *

View File

@ -3,7 +3,6 @@ package com.ff.game.api.meitian.client;
import com.dtflys.forest.annotation.Address; import com.dtflys.forest.annotation.Address;
import com.dtflys.forest.annotation.Post; import com.dtflys.forest.annotation.Post;
import com.dtflys.forest.annotation.Var; import com.dtflys.forest.annotation.Var;
import com.ff.game.api.km.dto.KMBalanceTransferStatusResponseDTO;
import com.ff.game.api.meitian.address.MeiTianAddressSource; import com.ff.game.api.meitian.address.MeiTianAddressSource;
import com.ff.game.api.meitian.dto.*; import com.ff.game.api.meitian.dto.*;
@ -104,22 +103,6 @@ public interface MeiTianClient {
@Var("data") String data @Var("data") String data
); );
/**
*
*
* @param merchantId ID
* @param playerName
* @param coins
* @return {@link MeiTianBalanceTransferStatusResponseDTO }
*/
@Post("dg/player/queryTransbyId/{playerName}/{merchantId}/{extTransId}")
MeiTianBalanceTransferStatusResponseDTO exchangeTransferStatus(
@Var("playerName") String merchantId,
@Var("merchantId") String playerName,
@Var("extTransId") String coins
);
/** /**
* recordId * recordId
* *

View File

@ -1,69 +0,0 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* dto
*
* @author shi
* @date 2025/04/08
*/
@Data
public class MeiTianBalanceTransferStatusResponseDTO {
/**
*
*/
@JsonProperty("resultCode")
private Integer resultCode;
/**
* ID
*/
@JsonProperty("transId")
private String transId;
/**
* yyyy-MM-dd HH:mm:ss
*/
@JsonProperty("transTime")
private String transTime;
/**
*
*/
@JsonProperty("transType")
private String transType;
/**
*
*/
@JsonProperty("transCoins")
private BigDecimal transCoins;
/**
*
*/
@JsonProperty("curBalance")
private BigDecimal curBalance;
/**
* GMT+8
*/
@JsonProperty("timeZone")
private String timeZone;
/**
* 1
*/
@JsonProperty("status")
private String status;
/**
* CNY
*/
@JsonProperty("currency")
private String currency;
}

View File

@ -22,7 +22,7 @@ public class MeiTianGameDataDTO {
/** /**
*id *id
*/ */
private String systemGameId; private Long systemGameId;
private String gameId; private String gameId;
private String cnName; private String cnName;
private String enName; private String enName;

View File

@ -2,7 +2,6 @@ package com.ff.game.api.meitian.impl;
import cn.hutool.core.codec.Base64; import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.ff.base.constant.CacheConstants; import com.ff.base.constant.CacheConstants;
import com.ff.base.constant.Constants; import com.ff.base.constant.Constants;
@ -10,13 +9,11 @@ import com.ff.base.core.redis.RedisCache;
import com.ff.base.enums.*; import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException; 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.domain.SysConfig;
import com.ff.base.system.service.impl.SysConfigServiceImpl; import com.ff.base.system.service.impl.SysConfigServiceImpl;
import com.ff.base.utils.DateUtils; import com.ff.base.utils.DateUtils;
import com.ff.base.utils.StringUtils;
import com.ff.base.utils.sign.Md5Utils; import com.ff.base.utils.sign.Md5Utils;
import com.ff.base.utils.uuid.IdUtils; import com.ff.base.utils.uuid.IdUtils;
import com.ff.delay.DelayService;
import com.ff.delay.DelayTask;
import com.ff.game.api.IGamesService; import com.ff.game.api.IGamesService;
import com.ff.game.api.meitian.client.MeiTianClient; import com.ff.game.api.meitian.client.MeiTianClient;
import com.ff.game.api.meitian.dto.*; import com.ff.game.api.meitian.dto.*;
@ -54,7 +51,7 @@ import java.util.stream.Collectors;
* @author shi * @author shi
* @date 2024/10/21 * @date 2024/10/21
*/ */
@Service("MTService") @Service("MeiTianService")
@Slf4j @Slf4j
public class MeiTianGameServiceImpl implements IGamesService { public class MeiTianGameServiceImpl implements IGamesService {
@ -80,9 +77,6 @@ public class MeiTianGameServiceImpl implements IGamesService {
@Autowired @Autowired
private SysConfigServiceImpl sysConfigServiceImpl; private SysConfigServiceImpl sysConfigServiceImpl;
@Autowired
private DelayService delayService;
/** /**
* *
* *
@ -223,8 +217,23 @@ public class MeiTianGameServiceImpl implements IGamesService {
MeiTianGamesDTO gameList = new MeiTianGamesDTO(); MeiTianGamesDTO gameList = new MeiTianGamesDTO();
for (MeiTianGameDataDTO gamesDataDTO : gameList.getData()) { for (MeiTianGameDataDTO gamesDataDTO : gameList.getData()) {
/* GamePlatform gamePlatform = GamePlatform.builder()
.platformType(MeiTianGameType.findSystemByCode(gamesDataDTO.getGameCategoryId()))
.platformCode(GamePlatforms.MT.getCode())
.build();
List<GamePlatform> gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform);
//没有此平台就新增一个平台
if (CollectionUtils.isEmpty(gamePlatforms)) {
gamePlatform.setPlatformName(GamePlatforms.MT.getInfo() + MeiTianGameType.findInfoByCode(gamesDataDTO.getGameCategoryId()));
gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1);
gamePlatform.setCreateBy(Constants.SYSTEM);
gamePlatformService.insertGamePlatform(gamePlatform);
} else {
gamePlatform = gamePlatforms.get(0);
}*/
Integer platformType = MeiTianGameType.findSystemByCode(gamesDataDTO.getGameCategoryId()); Integer platformType = MeiTianGameType.findSystemByCode(gamesDataDTO.getGameCategoryId());
Game game = Game.builder() Game game = Game.builder()
//.platformId(gamePlatform.getId())
.platformCode(GamePlatforms.MT.getCode()) .platformCode(GamePlatforms.MT.getCode())
.platformType(platformType) .platformType(platformType)
.gameCode(String.valueOf(gamesDataDTO.getGameId())) .gameCode(String.valueOf(gamesDataDTO.getGameId()))
@ -239,7 +248,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
game.setCreateBy(Constants.SYSTEM); game.setCreateBy(Constants.SYSTEM);
game.setPlatformType(platformType); game.setPlatformType(platformType);
game.setPlatformCode(GamePlatforms.MT.getCode()); game.setPlatformCode(GamePlatforms.MT.getCode());
game.setGameId(StringUtils.addSuffix(GamePlatforms.MT.getCode(), gamesDataDTO.getGameId()));
List<NameInfo> nameInfos = new ArrayList<>(); List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(new NameInfo(gamesDataDTO.getCnName(), "zh-CN")); nameInfos.add(new NameInfo(gamesDataDTO.getCnName(), "zh-CN"));
nameInfos.add(new NameInfo(gamesDataDTO.getEnName(), "en-US")); nameInfos.add(new NameInfo(gamesDataDTO.getEnName(), "en-US"));
@ -247,13 +256,25 @@ public class MeiTianGameServiceImpl implements IGamesService {
gameService.insertGame(game); gameService.insertGame(game);
} else { } else {
game = games.get(0); game = games.get(0);
List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(new NameInfo(gamesDataDTO.getCnName(), "zh-CN"));
nameInfos.add(new NameInfo(gamesDataDTO.getEnName(), "en-US"));
game.setNameInfo(nameInfos);
gameService.updateGame(game);
} }
gamesDataDTO.setSystemGameId(game.getGameId()); 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.deleteObject(CacheConstants.MeiTian_GAMES);
@ -263,17 +284,6 @@ public class MeiTianGameServiceImpl implements IGamesService {
return CacheConstants.MeiTian_GAMES; return CacheConstants.MeiTian_GAMES;
} }
/**
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
@Override
public String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO) {
return GamePlatforms.MT.getCode() + IdUtils.simpleUUID();
}
/** /**
* id * id
* *
@ -283,31 +293,49 @@ public class MeiTianGameServiceImpl implements IGamesService {
@Override @Override
@Transactional @Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .code(exchangeTransferMoneyRequestDTO.getAgentId())
// .currency(exchangeTransferMoneyRequestDTO.getCurrency()).build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId()); String transactionId = GamePlatforms.MT.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(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.MT.getCode())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
//接口限制限制50字符
exchangeMoney.setTransactionId(transactionId);
// String key = gameSecretKey.getKey();
String key = exchangeTransferMoneyRequestDTO.getAgentKey(); String key = exchangeTransferMoneyRequestDTO.getAgentKey();
String merchantId = exchangeTransferMoneyRequestDTO.getAgentId(); String merchantId = exchangeTransferMoneyRequestDTO.getAgentId();
String playerName = exchangeTransferMoneyRequestDTO.getAccount(); String playerName = exchangeTransferMoneyRequestDTO.getAccount();
String coins = exchangeTransferMoneyRequestDTO.getAmount().setScale(4, RoundingMode.DOWN).toString(); String coins = exchangeTransferMoneyRequestDTO.getAmount().setScale(4, RoundingMode.DOWN).toString();
if (exchangeTransferMoneyRequestDTO.getTransferType().equals(TransferType.ALL.getCode())) {
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.currency(exchangeTransferMoneyRequestDTO.getCurrency())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
.build();
coins = this.getMemberInfo(gamesBaseRequestDTO).getBalance().setScale(4, RoundingMode.DOWN).toString();
}
Map<String, String> rawMap = new LinkedHashMap<>(); Map<String, String> rawMap = new LinkedHashMap<>();
rawMap.put("merchantId", merchantId); rawMap.put("merchantId", merchantId);
rawMap.put("playerName", playerName); rawMap.put("playerName", playerName);
rawMap.put("extTransId", exchangeTransferMoneyRequestDTO.getTransactionId()); rawMap.put("extTransId", transactionId);
rawMap.put("coins", coins); rawMap.put("coins", coins);
String rawData = JSON.toJSONString(rawMap); String rawData = JSON.toJSONString(rawMap);
String data = null; String data = null;
@ -326,7 +354,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
merchantId, merchantId,
playerName, playerName,
coins, coins,
exchangeTransferMoneyRequestDTO.getTransactionId(), transactionId,
md5Code, md5Code,
data data
); );
@ -334,21 +362,16 @@ public class MeiTianGameServiceImpl implements IGamesService {
//判断是否转移成功 //判断是否转移成功
if (this.isSuccess(exchangeMoneyResponse.getErrorCode())) { if (this.isSuccess(exchangeMoneyResponse.getErrorCode())) {
//更新数据 //更新数据
BigDecimal transAmount = new BigDecimal(coins); exchangeMoney.setBalance(exchangeMoneyResponse.getBalance());
exchangeMoney.setBalance(transAmount); BigDecimal transAmount = exchangeTransferMoneyRequestDTO.getAmount();
exchangeMoney.setCoinBefore(exchangeMoneyResponse.getBalance().subtract(transAmount)); exchangeMoney.setCoinBefore(exchangeMoneyResponse.getBalance().subtract(transAmount));
exchangeMoney.setCoinAfter(exchangeMoneyResponse.getBalance()); exchangeMoney.setCoinAfter(exchangeMoneyResponse.getBalance());
exchangeMoney.setCurrencyBefore(exchangeMoneyResponse.getBalance().subtract(transAmount)); exchangeMoney.setCurrencyBefore(exchangeMoneyResponse.getBalance().subtract(transAmount));
exchangeMoney.setCurrencyAfter(exchangeMoneyResponse.getBalance()); exchangeMoney.setCurrencyAfter(exchangeMoneyResponse.getBalance());
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode()); exchangeMoney.setStatus(1); // SUCCESS
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode()); gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else { } else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
throw new BaseException(MeiTianExchangeMoneyResponseDTO.TransferIn.get(exchangeMoneyResponse.getErrorCode()).getMessage()); throw new BaseException(MeiTianExchangeMoneyResponseDTO.TransferIn.get(exchangeMoneyResponse.getErrorCode()).getMessage());
} }
@ -359,7 +382,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
merchantId, merchantId,
playerName, playerName,
coins, coins,
exchangeTransferMoneyRequestDTO.getTransactionId(), transactionId,
md5Code, md5Code,
data data
); );
@ -367,20 +390,15 @@ public class MeiTianGameServiceImpl implements IGamesService {
//判断是否转移成功 //判断是否转移成功
if (this.isSuccess(exchangeMoneyResponse.getErrorCode())) { if (this.isSuccess(exchangeMoneyResponse.getErrorCode())) {
//更新数据 //更新数据
BigDecimal transAmount = new BigDecimal(coins); exchangeMoney.setBalance(exchangeMoneyResponse.getBalance());
exchangeMoney.setBalance(transAmount); BigDecimal transAmount = exchangeTransferMoneyRequestDTO.getAmount();
exchangeMoney.setCoinBefore(exchangeMoneyResponse.getBalance().add(transAmount)); exchangeMoney.setCoinBefore(exchangeMoneyResponse.getBalance().add(transAmount));
exchangeMoney.setCoinAfter(exchangeMoneyResponse.getBalance()); exchangeMoney.setCoinAfter(exchangeMoneyResponse.getBalance());
exchangeMoney.setCurrencyBefore(exchangeMoneyResponse.getBalance().add(transAmount)); exchangeMoney.setCurrencyBefore(exchangeMoneyResponse.getBalance().add(transAmount));
exchangeMoney.setCurrencyAfter(exchangeMoneyResponse.getBalance()); exchangeMoney.setCurrencyAfter(exchangeMoneyResponse.getBalance());
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode()); exchangeMoney.setStatus(1); // SUCCESS
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode()); gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else { } else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
throw new BaseException(MeiTianExchangeMoneyResponseDTO.TransferOut.get(exchangeMoneyResponse.getErrorCode()).getMessage()); throw new BaseException(MeiTianExchangeMoneyResponseDTO.TransferOut.get(exchangeMoneyResponse.getErrorCode()).getMessage());
} }
} }
@ -394,61 +412,11 @@ public class MeiTianGameServiceImpl implements IGamesService {
* @return {@link Boolean } * @return {@link Boolean }
*/ */
@Override @Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("MeiTianGameServiceImpl [exchangeTransferStatus] 请求参数 {}", exchangeTransferMoneyRequestDTO); return Boolean.TRUE;
String merchantId = exchangeTransferMoneyRequestDTO.getAgentId();
String playerName = exchangeTransferMoneyRequestDTO.getAccount();
MeiTianBalanceTransferStatusResponseDTO meiTianBalanceTransferStatusResponseDTO = meiTianClient.exchangeTransferStatus(
playerName,
merchantId,
exchangeTransferMoneyRequestDTO.getOrderId()
);
Integer status = StatusType.IN_PROGRESS.getValue();
if (this.isSuccess(meiTianBalanceTransferStatusResponseDTO.getResultCode()) && "1".equals(meiTianBalanceTransferStatusResponseDTO.getStatus())) {
status = StatusType.SUCCESS.getValue();
} else {
status = StatusType.FAILURE.getValue();
}
return ExchangeTransferStatusResponseDTO.builder()
.statusType(status)
.balance(meiTianBalanceTransferStatusResponseDTO.getTransCoins())
.coinBefore(NumberUtil.sub(meiTianBalanceTransferStatusResponseDTO.getTransCoins(), meiTianBalanceTransferStatusResponseDTO.getCurBalance()).abs())
.coinAfter(meiTianBalanceTransferStatusResponseDTO.getCurBalance())
.build();
} }
class GetRecordByTimeTask extends DelayTask {
BetRecordByTimeDTO betRecordByTimeDTO;
public GetRecordByTimeTask(BetRecordByTimeDTO betRecordByTimeDTO) {
this.betRecordByTimeDTO = betRecordByTimeDTO;
}
@Override
public void execute() {
doSyncRecordByRecordID(betRecordByTimeDTO);
}
}
class GetRecordByHistoryTimeTask extends DelayTask {
BetRecordByTimeDTO betRecordByTimeDTO;
public GetRecordByHistoryTimeTask(BetRecordByTimeDTO betRecordByTimeDTO) {
this.betRecordByTimeDTO = betRecordByTimeDTO;
}
@Override
public void execute() {
doSyncRecordByDate(betRecordByTimeDTO, 1);
}
}
/** /**
* *
* *
@ -457,21 +425,18 @@ public class MeiTianGameServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
delayService.addTask(new GetRecordByTimeTask(betRecordByTimeDTO)); return doSyncRecordByRecordID(betRecordByTimeDTO);
return Boolean.TRUE;
//return doSyncRecordByRecordID(betRecordByTimeDTO);
} }
boolean doSyncRecordByRecordID(BetRecordByTimeDTO betRecordByTimeDTO) { boolean doSyncRecordByRecordID(BetRecordByTimeDTO betRecordByTimeDTO) {
String configKey = GamePlatforms.MT.getCode() + ":lastSyncRecordID"; String configKey = GamePlatforms.MT.getCode() + ":lastRecordID";
Long recordID = redisCache.getCacheObject(configKey); String lastRecordID = sysConfigServiceImpl.selectConfigByKey(configKey);
long recordID = 0;
//String lastRecordID = sysConfigServiceImpl.selectConfigByKey(configKey); if (lastRecordID == null || lastRecordID.isEmpty()) {
/*if (lastRecordID == null || lastRecordID.isEmpty()) {
} else { } else {
recordID = Long.parseLong(lastRecordID); recordID = Long.parseLong(lastRecordID);
}*/ }
String merchantId = betRecordByTimeDTO.getAgentId(); String merchantId = betRecordByTimeDTO.getAgentId();
Map<String, Object> rawMap = new LinkedHashMap<>(); Map<String, Object> rawMap = new LinkedHashMap<>();
rawMap.put("recordID", recordID); rawMap.put("recordID", recordID);
@ -497,9 +462,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
//数据插入 //数据插入
this.batchInsert(recordResponse, betRecordByTimeDTO); this.batchInsert(recordResponse, betRecordByTimeDTO);
MeiTianBetRecordResponseDTO.DataBean dataBean = dataList.get(dataList.size() - 1); MeiTianBetRecordResponseDTO.DataBean dataBean = dataList.get(dataList.size() - 1);
redisCache.setCacheObject(configKey, Long.parseLong(dataBean.getRowID())); SysConfig config = sysConfigServiceImpl.getByConfigKey(configKey);
/*SysConfig config = sysConfigServiceImpl.getByConfigKey(configKey);
if (config == null) { if (config == null) {
config = new SysConfig(); config = new SysConfig();
config.setConfigKey(configKey); config.setConfigKey(configKey);
@ -508,7 +471,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
} else { } else {
config.setConfigValue(dataBean.getRecordID()); config.setConfigValue(dataBean.getRecordID());
sysConfigServiceImpl.updateConfig(config); sysConfigServiceImpl.updateConfig(config);
}*/ }
// 它每次返回25000条所以需要判断如果大于25000条则继续拉取 // 它每次返回25000条所以需要判断如果大于25000条则继续拉取
if (dataList.size() >= 25000) { if (dataList.size() >= 25000) {
doSyncRecordByRecordID(betRecordByTimeDTO); doSyncRecordByRecordID(betRecordByTimeDTO);
@ -524,7 +487,22 @@ public class MeiTianGameServiceImpl implements IGamesService {
String date = getDateStr(daysToSubtract); String date = getDateStr(daysToSubtract);
String configKey = GamePlatforms.MT.getCode() + ":lastSyncDate"; String configKey = GamePlatforms.MT.getCode() + ":lastSyncDate";
long recordID = redisCache.getCacheObject(configKey); String syncDateStr = sysConfigServiceImpl.selectConfigByKey(configKey);
Map<String, Long> syncDateMap = new HashMap<>();
long recordID = 0;
if (syncDateStr == null || syncDateStr.isEmpty()) {
} else {
syncDateMap = JSON.parseObject(syncDateStr, Map.class);
}
if (syncDateMap.containsKey(date)) {
recordID = syncDateMap.get(date);
if (syncDateMap.size() > 10) {
syncDateMap.clear();
syncDateMap.put(date, recordID);
}
} else {
syncDateMap.put(date, recordID);
}
String merchantId = betRecordByTimeDTO.getAgentId(); String merchantId = betRecordByTimeDTO.getAgentId();
Map<String, Object> rawMap = new LinkedHashMap<>(); Map<String, Object> rawMap = new LinkedHashMap<>();
rawMap.put("rowID", recordID); rawMap.put("rowID", recordID);
@ -552,9 +530,8 @@ public class MeiTianGameServiceImpl implements IGamesService {
//数据插入 //数据插入
this.batchInsert(recordResponse, betRecordByTimeDTO); this.batchInsert(recordResponse, betRecordByTimeDTO);
MeiTianBetRecordResponseDTO.DataBean dataBean = dataList.get(dataList.size() - 1); MeiTianBetRecordResponseDTO.DataBean dataBean = dataList.get(dataList.size() - 1);
//syncDateMap.put(date, Long.parseLong(dataBean.getRowID())); syncDateMap.put(date, Long.parseLong(dataBean.getRowID()));
redisCache.setCacheObject(configKey, Long.parseLong(dataBean.getRowID())); SysConfig config = sysConfigServiceImpl.getByConfigKey(configKey);
/*SysConfig config = sysConfigServiceImpl.getByConfigKey(configKey);
if (null == config) { if (null == config) {
config = new SysConfig(); config = new SysConfig();
config.setConfigKey(configKey); config.setConfigKey(configKey);
@ -563,7 +540,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
} else { } else {
config.setConfigValue(JSON.toJSONString(syncDateMap)); config.setConfigValue(JSON.toJSONString(syncDateMap));
sysConfigServiceImpl.updateConfig(config); sysConfigServiceImpl.updateConfig(config);
}*/ }
// 它每次返回25000条所以需要判断如果大于25000条则继续拉取 // 它每次返回25000条所以需要判断如果大于25000条则继续拉取
if (dataList.size() >= 25000) { if (dataList.size() >= 25000) {
@ -584,10 +561,9 @@ public class MeiTianGameServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
//doSyncRecordByDate(betRecordByTimeDTO, 0); doSyncRecordByDate(betRecordByTimeDTO, 0);
//doSyncRecordByDate(betRecordByTimeDTO, 1); // yesterday doSyncRecordByDate(betRecordByTimeDTO, 1); // yesterday
delayService.addTask(new GetRecordByHistoryTimeTask(betRecordByTimeDTO));
return true; return true;
} }
@ -817,6 +793,10 @@ public class MeiTianGameServiceImpl implements IGamesService {
} }
} }
public LocalDate getDate(int daysToSubtract) {
return LocalDate.now().minusDays(daysToSubtract); // 获取当前日期减去两天
}
public String getDateStr(int daysToSubtract) { public String getDateStr(int daysToSubtract) {
// 获取当前日期减去指定天数 // 获取当前日期减去指定天数
LocalDate date = LocalDate.now().minusDays(daysToSubtract); LocalDate date = LocalDate.now().minusDays(daysToSubtract);

View File

@ -18,6 +18,7 @@ public class MyNGAddressSource implements AddressSource {
@Override @Override
public ForestAddress getAddress(ForestRequest request) { public ForestAddress getAddress(ForestRequest request) {
//String apiBaseUrl = configService.selectConfigByKey(Constants.NG_API_BASE_URL);
String apiBaseUrl = platformService.get(GamePlatforms.PG.getCode()) String apiBaseUrl = platformService.get(GamePlatforms.PG.getCode())
.getUrlInfo().getUrl(); .getUrlInfo().getUrl();
return new ForestAddress("https", apiBaseUrl, 443, "api"); return new ForestAddress("https", apiBaseUrl, 443, "api");

View File

@ -13,7 +13,6 @@ import com.ff.base.utils.DateUtils;
import com.ff.base.utils.SleepUtil; import com.ff.base.utils.SleepUtil;
import com.ff.base.utils.StringUtils; import com.ff.base.utils.StringUtils;
import com.ff.base.utils.sign.Md5Utils; import com.ff.base.utils.sign.Md5Utils;
import com.ff.base.utils.uuid.IdUtils;
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.ng.client.NGClient; import com.ff.game.api.ng.client.NGClient;
@ -233,8 +232,23 @@ public class GamesPGServiceImpl implements IGamesService {
ApiNGResponseDTO<List<ApiGameInfoResponseDTO>> gameList = ngClient.getGameList(paramsMap, headerMap); ApiNGResponseDTO<List<ApiGameInfoResponseDTO>> gameList = ngClient.getGameList(paramsMap, headerMap);
if (this.getIsSuccess(gameList.getCode())) { if (this.getIsSuccess(gameList.getCode())) {
for (ApiGameInfoResponseDTO apiGameInfoResponseDTO : gameList.getData()) { for (ApiGameInfoResponseDTO apiGameInfoResponseDTO : gameList.getData()) {
/*GamePlatform gamePlatform = GamePlatform.builder()
.platformType(NGGameType.findSystemByCode(apiGameInfoResponseDTO.getGameType()))
.platformCode(GamePlatforms.PG.getCode())
.build();
List<GamePlatform> gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform);
//没有此平台就新增一个平台
if (CollectionUtils.isEmpty(gamePlatforms)) {
gamePlatform.setPlatformName(GamePlatforms.PG.getInfo() + NGGameType.findInfoByCode(apiGameInfoResponseDTO.getGameType()));
gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1);
gamePlatform.setCreateBy(Constants.SYSTEM);
gamePlatformService.insertGamePlatform(gamePlatform);
} else {
gamePlatform = gamePlatforms.get(0);
}*/
Integer platformType = NGGameType.findSystemByCode(apiGameInfoResponseDTO.getGameType()); Integer platformType = NGGameType.findSystemByCode(apiGameInfoResponseDTO.getGameType());
Game game = Game.builder() Game game = Game.builder()
// .platformId(gamePlatform.getId())
.platformCode(GamePlatforms.PG.getCode()) .platformCode(GamePlatforms.PG.getCode())
.platformType(platformType) .platformType(platformType)
.gameCode(apiGameInfoResponseDTO.getGameCode()) .gameCode(apiGameInfoResponseDTO.getGameCode())
@ -250,7 +264,6 @@ public class GamesPGServiceImpl implements IGamesService {
game.setCreateBy(Constants.SYSTEM); game.setCreateBy(Constants.SYSTEM);
game.setPlatformCode(GamePlatforms.PG.getCode()); game.setPlatformCode(GamePlatforms.PG.getCode());
game.setPlatformType(platformType); game.setPlatformType(platformType);
game.setGameId(StringUtils.addSuffix(GamePlatforms.PG.getCode(), apiGameInfoResponseDTO.getGameCode()));
List<NameInfo> nameInfos = new ArrayList<>(); List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(new NameInfo(apiGameInfoResponseDTO.getGameName().get("zh-hans"), "zh-CN")); nameInfos.add(new NameInfo(apiGameInfoResponseDTO.getGameName().get("zh-hans"), "zh-CN"));
nameInfos.add(new NameInfo(apiGameInfoResponseDTO.getGameName().get("zh-hant"), "zh-TW")); nameInfos.add(new NameInfo(apiGameInfoResponseDTO.getGameName().get("zh-hant"), "zh-TW"));
@ -259,14 +272,34 @@ public class GamesPGServiceImpl implements IGamesService {
gameService.insertGame(game); gameService.insertGame(game);
} else { } else {
game = games.get(0); game = games.get(0);
List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(new NameInfo(apiGameInfoResponseDTO.getGameName().get("zh-hans"), "zh-CN"));
nameInfos.add(new NameInfo(apiGameInfoResponseDTO.getGameName().get("zh-hant"), "zh-TW"));
nameInfos.add(new NameInfo(apiGameInfoResponseDTO.getGameName().get("en"), "en-US"));
game.setNameInfo(nameInfos);
gameService.updateGame(game);
} }
apiGameInfoResponseDTO.setSystemGameId(game.getId()); apiGameInfoResponseDTO.setSystemGameId(game.getId());
/*Map<String, String> gameName = apiGameInfoResponseDTO.getGameName();
for (String key : gameName.keySet()) {
String name = gameName.get(key);
List<GameName> gameNames = gameNameService.selectGameNameList(GameName.builder().gameId(game.getId()).gameName(name).build());
if (CollectionUtils.isEmpty(gameNames)) {
if ("zh-hans".equals(key)) {
gameNameService.insertGameName(GameName.builder()
.gameId(game.getId())
.gameName(name)
.langCode("zh-CN")
.createBy(Constants.SYSTEM)
.build());
} else if (!"zh-hant".equals(key)) {
GameSecretKeyLangDTO gameSecretKeyLangDTO = gameSecretKeyLangService.findGameSecretKeyLangDTO(GameSecretKeyLangDTO.builder()
.platformCode(GamePlatforms.PG.getCode())
.lang(key)
.build());
gameNameService.insertGameName(GameName.builder()
.gameId(game.getId())
.gameName(name)
.langCode(gameSecretKeyLangDTO.getSystemLangCode())
.createBy(Constants.SYSTEM)
.build());
}
}
}*/
} }
@ -280,19 +313,6 @@ public class GamesPGServiceImpl implements IGamesService {
return CacheConstants.PG_GAMES; return CacheConstants.PG_GAMES;
} }
/**
* id
*
* @param transactionIdRequestDTO iddto
* @return {@link String }
*/
@Override
public String getTransactionId(TransactionIdRequestDTO transactionIdRequestDTO) {
return gameExchangeMoneyService.getTransactionId(GamePlatforms.PG.getCode(), 32);
}
/** /**
* id * id
* *
@ -304,28 +324,50 @@ public class GamesPGServiceImpl implements IGamesService {
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesNGServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesNGServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.PG.getCode())
// .code(exchangeTransferMoneyRequestDTO.getAgentId())
// .currency(exchangeTransferMoneyRequestDTO.getCurrency())
// .build());
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId()); Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = gameExchangeMoneyService.getTransactionId(GamePlatforms.PG.getCode(), 32);
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.PG.getCode())
.build();
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()) ? NGTransferType.TRANSFER_OUT.getValue() : NGTransferType.TRANSFER_IN.getValue();
//获取当前游戏币 //获取当前游戏币
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(exchangeTransferMoneyRequestDTO.getAccount()) .accounts(member.getGameAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId()) .agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey()) .agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()) .currency(exchangeTransferMoneyRequestDTO.getCurrency())
.build(); .build();
MemberInfoResponseDTO memberInfo = this.getMemberInfo(gamesBaseRequestDTO);
//判断是不是转出 //判断是不是转出
if (NGTransferType.TRANSFER_OUT.getValue().equals(type)) { if (NGTransferType.TRANSFER_OUT.getValue().equals(type)) {
MemberInfoResponseDTO memberInfo = this.getMemberInfo(gamesBaseRequestDTO);
exchangeTransferMoneyRequestDTO.setAmount(memberInfo.getBalance()); exchangeTransferMoneyRequestDTO.setAmount(memberInfo.getBalance());
if (exchangeTransferMoneyRequestDTO.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
throw new ApiException(ErrorCode.INSUFFICIENT_PLAYER_BALANCE.getCode());
}
} }
@ -335,7 +377,7 @@ public class GamesPGServiceImpl implements IGamesService {
paramsMap.put("currency", exchangeTransferMoneyRequestDTO.getCurrency()); paramsMap.put("currency", exchangeTransferMoneyRequestDTO.getCurrency());
paramsMap.put("type", type); paramsMap.put("type", type);
paramsMap.put("amount", exchangeTransferMoneyRequestDTO.getAmount()); paramsMap.put("amount", exchangeTransferMoneyRequestDTO.getAmount());
paramsMap.put("orderId", exchangeTransferMoneyRequestDTO.getTransactionId()); paramsMap.put("orderId", transactionId);
Map<String, String> key = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, String> key = this.getKey(exchangeTransferMoneyRequestDTO);
@ -343,27 +385,16 @@ public class GamesPGServiceImpl implements IGamesService {
if (this.getIsSuccess(apiNGResponseDTO.getCode())) { if (this.getIsSuccess(apiNGResponseDTO.getCode())) {
//更新数据 //更新数据
exchangeMoney.setBalance(exchangeTransferMoneyRequestDTO.getAmount()); exchangeMoney.setBalance(exchangeTransferMoneyRequestDTO.getAmount());
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode()); exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode()); gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
ExchangeTransferStatusRequestDTO exchangeTransferStatusRequestDTO = new ExchangeTransferStatusRequestDTO(); ExchangeTransferStatusRequestDTO exchangeTransferStatusRequestDTO = new ExchangeTransferStatusRequestDTO();
exchangeTransferStatusRequestDTO.setAccount(exchangeTransferMoneyRequestDTO.getAccount()); exchangeTransferStatusRequestDTO.setAccount(exchangeTransferMoneyRequestDTO.getAccount());
exchangeTransferStatusRequestDTO.setCurrency(exchangeTransferMoneyRequestDTO.getCurrency()); exchangeTransferStatusRequestDTO.setCurrency(exchangeTransferMoneyRequestDTO.getCurrency());
exchangeTransferStatusRequestDTO.setOrderId(exchangeTransferMoneyRequestDTO.getTransactionId()); exchangeTransferStatusRequestDTO.setOrderId(transactionId);
exchangeTransferStatusRequestDTO.setAgentId(exchangeTransferMoneyRequestDTO.getAgentId()); exchangeTransferStatusRequestDTO.setAgentId(exchangeTransferMoneyRequestDTO.getAgentId());
exchangeTransferStatusRequestDTO.setAgentKey(exchangeTransferMoneyRequestDTO.getAgentKey()); exchangeTransferStatusRequestDTO.setAgentKey(exchangeTransferMoneyRequestDTO.getAgentKey());
ExchangeTransferStatusResponseDTO statusResponseDTO = this.exchangeTransferStatus(exchangeTransferStatusRequestDTO); this.exchangeTransferStatus(exchangeTransferStatusRequestDTO);
//更新钱
exchangeMoney.setBalance(statusResponseDTO.getBalance());
exchangeMoney.setCoinBefore(statusResponseDTO.getCoinBefore());
exchangeMoney.setCoinAfter(statusResponseDTO.getCoinAfter());
exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore());
exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else { } else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
log.error("GamesPGServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", apiNGResponseDTO.getCode(), apiNGResponseDTO.getMsg()); log.error("GamesPGServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", apiNGResponseDTO.getCode(), apiNGResponseDTO.getMsg());
throw new BaseException(apiNGResponseDTO.getMsg()); throw new BaseException(apiNGResponseDTO.getMsg());
} }
@ -377,9 +408,8 @@ public class GamesPGServiceImpl implements IGamesService {
* @return {@link Boolean } * @return {@link Boolean }
*/ */
@Override @Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
SleepUtil.sleep(1000);
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("playerId", exchangeTransferMoneyRequestDTO.getAccount()); paramsMap.put("playerId", exchangeTransferMoneyRequestDTO.getAccount());
@ -387,24 +417,32 @@ public class GamesPGServiceImpl implements IGamesService {
paramsMap.put("orderId", exchangeTransferMoneyRequestDTO.getOrderId()); paramsMap.put("orderId", exchangeTransferMoneyRequestDTO.getOrderId());
Map<String, String> key = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, String> key = this.getKey(exchangeTransferMoneyRequestDTO);
ApiNGResponseDTO<ApiExchangeTransferStatusResponseDTO> apiNGResponseDTO = ngClient.exchangeTransferStatus(paramsMap, key); ApiNGResponseDTO<ApiExchangeTransferStatusResponseDTO> apiNGResponseDTO = ngClient.exchangeTransferStatus(paramsMap, key);
Integer status = StatusType.IN_PROGRESS.getValue();
if (this.getIsSuccess(apiNGResponseDTO.getCode())) { if (this.getIsSuccess(apiNGResponseDTO.getCode())) {
status = StatusType.SUCCESS.getValue();
} else {
status = StatusType.FAILURE.getValue();
}
ExchangeTransferStatusResponseDTO transferStatusResponseDTO = ExchangeTransferStatusResponseDTO.builder()
.statusType(status)
.build();
ApiExchangeTransferStatusResponseDTO apiNGResponseDTOData = apiNGResponseDTO.getData(); ApiExchangeTransferStatusResponseDTO apiNGResponseDTOData = apiNGResponseDTO.getData();
if (!ObjectUtils.isEmpty(apiNGResponseDTOData)) { List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
transferStatusResponseDTO.setBalance(apiNGResponseDTOData.getAmount().abs()); GameExchangeMoney.builder()
transferStatusResponseDTO.setCoinBefore(NumberUtil.sub(apiNGResponseDTOData.getAmount(), apiNGResponseDTOData.getAfterBalance()).abs()); .platformCode(GamePlatforms.PG.getCode())
transferStatusResponseDTO.setCoinAfter(apiNGResponseDTOData.getAfterBalance()); .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;
} else {
log.error("GamesPGServiceImpl [exchangeTransferStatus]错误代码{},错误信息{}", apiNGResponseDTO.getCode(), apiNGResponseDTO.getMsg());
return Boolean.FALSE;
} }
return transferStatusResponseDTO;
} }
@ -417,6 +455,14 @@ public class GamesPGServiceImpl 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());
Platform platform = betRecordByTimeDTO.getVendor(); Platform platform = betRecordByTimeDTO.getVendor();
Set<String> cacheSet = redisCache.getCacheSet(CacheConstants.PG_GAMES_BET_CURRENCY); Set<String> cacheSet = redisCache.getCacheSet(CacheConstants.PG_GAMES_BET_CURRENCY);
@ -434,7 +480,14 @@ public class GamesPGServiceImpl implements IGamesService {
String firstCurrency = currencys.get(0); String firstCurrency = currencys.get(0);
// GameSecretKeyCurrencyDTO currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.PG.getCode())
// .currency(firstCurrency)
// .build());
// betRecordByTimeDTO.setAgentId(currencyDTO.getCode());
// betRecordByTimeDTO.setAgentKey(currencyDTO.getKey());
int pageNo = 1; int pageNo = 1;
int pageSize = 2000; int pageSize = 2000;
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
@ -700,6 +753,10 @@ public class GamesPGServiceImpl implements IGamesService {
return null; return null;
} }
Game gamesDataDTO = games.get(0); Game gamesDataDTO = games.get(0);
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCodes(NGPlatforms.getAllPlatforms())
// .currency(resultBean.getCurrency())
// .build());
Member member = memberService.selectMemberByGameAccount(resultBean.getPlayerId()); Member member = memberService.selectMemberByGameAccount(resultBean.getPlayerId());
if (ObjectUtils.isEmpty(member)) { if (ObjectUtils.isEmpty(member)) {
@ -724,7 +781,7 @@ public class GamesPGServiceImpl implements IGamesService {
.gameCode(gamesDataDTO.getGameCode()) .gameCode(gamesDataDTO.getGameCode())
.gameType(NGGameType.findSystemByCode(resultBean.getGameType())) .gameType(NGGameType.findSystemByCode(resultBean.getGameType()))
.platformCode(NGPlatforms.getByCode(resultBean.getPlatType()).getPlatform()) .platformCode(NGPlatforms.getByCode(resultBean.getPlatType()).getPlatform())
.gameId(gamesDataDTO.getGameId()) .gameId(gamesDataDTO.getId())
.gameName(gamesDataDTO.getGameName()) .gameName(gamesDataDTO.getGameName())
.gameStatus(gameStatus) .gameStatus(gameStatus)
.gameStatusType(1) .gameStatusType(1)

View File

@ -1,35 +0,0 @@
package com.ff.game.api.pgt.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.enums.GamePlatforms;
import com.ff.base.system.service.ISysConfigService;
import com.ff.game.service.IPlatformService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* pt
*
* @author shi
* @date 2025/02/10
*/
@Component
public class MyPGTAddressSource implements AddressSource {
@Resource
private IPlatformService platformService;
@Resource
private ISysConfigService configService;
@Override
public ForestAddress getAddress(ForestRequest request) {
String apiBaseUrl = platformService.get(GamePlatforms.PGT.getCode())
.getUrlInfo().getUrl();
return new ForestAddress("https",apiBaseUrl, 443,"");
}
}

View File

@ -1,139 +0,0 @@
package com.ff.game.api.pgt.client;
import com.dtflys.forest.annotation.*;
import com.ff.game.api.dg.dto.DGResponse;
import com.ff.game.api.fc.dto.ApiFCGameListResponseDTO;
import com.ff.game.api.jili.dto.JILIKickMemberAllDTO;
import com.ff.game.api.jili.dto.JILIKickMemberDTO;
import com.ff.game.api.ng.dto.ApiExchangeTransferStatusResponseDTO;
import com.ff.game.api.ng.dto.ApiNGResponseDTO;
import com.ff.game.api.pgt.address.MyPGTAddressSource;
import com.ff.game.api.pgt.dto.*;
import com.ff.game.api.pgx.dto.PGXPlayerStatusResponse;
import com.ff.game.api.success.MySuccessCondition;
import com.ff.game.api.xk.dto.XKKickMemberAllDTO;
import java.util.Map;
/**
* pt
*
* @author shi
* @date 2025/02/10
*/
@Address(source = MyPGTAddressSource.class)
@Success(condition = MySuccessCondition.class)
public interface PGTClient {
/**
*
*
* @param parameters
* @param headerMap
* @return {@link String }
*/
@Post("/member")
PGTCreateMemberResponse createMember(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @return {@link PGTBalanceResponse }
*/
@Get("/balance?${parameters}")
PGTBalanceResponse getMemberInfo(@Var("parameters") String parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @return {@link PGTLoginResponse }
*/
@Post("/logIn")
PGTLoginResponse loginWithoutRedirect(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @param headerMap
* @return {@link PGTGameListResponse }
*/
@Get("/games?${parameters}")
PGTGameListResponse getGameList(@Var("parameters") String parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @param headerMap
* @return {@link PGTExchangeTransferResponse }
*/
@Post(url = "/deposit")
PGTExchangeTransferResponse deposit(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @param headerMap
* @return {@link PGTExchangeTransferResponse }
*/
@Post(url = "/withdraw")
PGTExchangeTransferResponse withdraw(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @param headerMap
* @return {@link ApiNGResponseDTO }<{@link ApiExchangeTransferStatusResponseDTO }>
*/
@Post(url = "/verifyDepositWithdraw")
PGTTransactionResponse exchangeTransferStatus(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @param headerMap
* @return {@link PGTTransactionDetailsResponse }
*/
@Get(url = "/betTransactionsV2?{parameters}")
PGTTransactionDetailsResponse getBetRecordByTime(@Var("parameters") String parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @param headerMap
* @return {@link PGTReplayUrlResponseDTO }
*/
@Get(url = "/betTransactionReplay?{parameters}")
PGTReplayUrlResponseDTO betTransactionReplay(@Var("parameters") String parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @param headerMap
* @return {@link PGTKickMemberResponse }
*/
@Post("/seamless/kickOutPlayer")
PGTKickMemberResponse kickMember(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap);
}

Some files were not shown because too many files have changed in this diff Show More