feat(fb): 新增 FB 体育平台支持
- 添加 FB 体育相关的数据结构和接口定义 - 实现 FB 体育平台的会员创建、资金转账、获取会员信息等功能 - 集成 FB 体育平台的 URL 获取和登录逻辑 - 为 FB 体育平台添加错误码定义 -优化游戏列表获取逻辑,支持 FB 体育游戏数据同步main-meitian
parent
f35179c8bc
commit
72810d4d0e
|
@ -84,6 +84,10 @@ 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:";
|
||||||
/**
|
/**
|
||||||
* pg游戏投注货币
|
* pg游戏投注货币
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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,6 +30,12 @@ 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失败")
|
||||||
;
|
;
|
||||||
|
|
||||||
// 获取错误码
|
// 获取错误码
|
||||||
|
|
|
@ -13,8 +13,9 @@ 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"),
|
||||||
;
|
|
||||||
|
FBSports("FBSports", "FB体育");
|
||||||
|
|
||||||
private final String code;
|
private final String code;
|
||||||
private final String info;
|
private final String info;
|
||||||
|
|
|
@ -75,9 +75,6 @@ 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;
|
||||||
|
|
||||||
|
|
|
@ -1,42 +1,40 @@
|
||||||
package com.ff.common.service.impl;
|
package com.ff.common.service.impl;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import com.ff.base.constant.Constants;
|
import com.ff.base.constant.Constants;
|
||||||
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.system.domain.TenantPlatform;
|
import com.ff.base.system.domain.TenantPlatform;
|
||||||
|
import com.ff.base.system.domain.TenantSecretKey;
|
||||||
import com.ff.base.system.service.ITenantPlatformService;
|
import com.ff.base.system.service.ITenantPlatformService;
|
||||||
|
import com.ff.base.system.service.ITenantSecretKeyService;
|
||||||
import com.ff.base.utils.DateUtils;
|
import com.ff.base.utils.DateUtils;
|
||||||
import com.ff.base.utils.QuotaUtils;
|
import com.ff.base.utils.QuotaUtils;
|
||||||
import com.ff.base.utils.StringUtils;
|
import com.ff.common.domain.TenantGameQuota;
|
||||||
import com.ff.common.domain.TenantGameQuotaFlow;
|
import com.ff.common.domain.TenantGameQuotaFlow;
|
||||||
import com.ff.common.domain.TenantQuotaExchange;
|
import com.ff.common.domain.TenantQuotaExchange;
|
||||||
import com.ff.base.system.domain.TenantSecretKey;
|
|
||||||
import com.ff.common.dto.BalanceChangesDTO;
|
import com.ff.common.dto.BalanceChangesDTO;
|
||||||
import com.ff.common.dto.BalanceRealChangesDTO;
|
import com.ff.common.dto.BalanceRealChangesDTO;
|
||||||
import com.ff.common.dto.GameBalanceExchange;
|
import com.ff.common.dto.GameBalanceExchange;
|
||||||
|
import com.ff.common.mapper.TenantGameQuotaMapper;
|
||||||
import com.ff.common.service.ITenantGameQuotaFlowService;
|
import com.ff.common.service.ITenantGameQuotaFlowService;
|
||||||
|
import com.ff.common.service.ITenantGameQuotaService;
|
||||||
import com.ff.common.service.ITenantQuotaExchangeService;
|
import com.ff.common.service.ITenantQuotaExchangeService;
|
||||||
import com.ff.base.system.service.ITenantSecretKeyService;
|
|
||||||
import com.ff.game.api.IGamesService;
|
import com.ff.game.api.IGamesService;
|
||||||
import com.ff.game.api.request.MemberInfoRequestDTO;
|
import com.ff.game.api.request.MemberInfoRequestDTO;
|
||||||
import com.ff.member.domain.Member;
|
import com.ff.member.domain.Member;
|
||||||
import com.ff.member.service.IMemberService;
|
import com.ff.member.service.IMemberService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.ff.common.mapper.TenantGameQuotaMapper;
|
|
||||||
import com.ff.common.domain.TenantGameQuota;
|
|
||||||
import com.ff.common.service.ITenantGameQuotaService;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 租户游戏配额Service业务层处理
|
* 租户游戏配额Service业务层处理
|
||||||
|
@ -296,14 +294,11 @@ 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());
|
||||||
|
|
||||||
|
@ -332,6 +327,11 @@ 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)));
|
||||||
|
|
||||||
// 计算累计转入和转出金额
|
// 计算累计转入和转出金额
|
||||||
|
@ -393,12 +393,10 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
|
||||||
// 如果是扣账操作,首先处理假额度
|
// 如果是扣账操作,首先处理假额度
|
||||||
String falseTenantQuotaType = QuotaUtils.getFalseTenantQuota(gameBalanceExchange.getPlatformCode(), gameBalanceExchange.getCurrencyCode());
|
String falseTenantQuotaType = QuotaUtils.getFalseTenantQuota(gameBalanceExchange.getPlatformCode(), gameBalanceExchange.getCurrencyCode());
|
||||||
TenantGameQuota falseTenantQuota = selectTenantGameQuotaByTenantKey(tenantSecretKey.getTenantKey(), falseTenantQuotaType);
|
TenantGameQuota falseTenantQuota = selectTenantGameQuotaByTenantKey(tenantSecretKey.getTenantKey(), falseTenantQuotaType);
|
||||||
balanceRequestAmount = NumberUtil.add(gameBalanceExchange.getAmount(), NumberUtil.mul(gameBalanceExchange.getAmount(), NumberUtil.div(tenantPlatform.getUseCost(), Constants.HUNDRED)));
|
balanceRequestAmount = NumberUtil.add(gameBalanceExchange.getAmount(), NumberUtil.mul(gameBalanceExchange.getAmount(), NumberUtil.div(tenantPlatform.getUseCost(), Constants.HUNDRED)));
|
||||||
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) {
|
||||||
// 假额度足够扣除本次所需金额
|
// 假额度足够扣除本次所需金额
|
||||||
|
|
|
@ -24,6 +24,8 @@ import com.ff.game.service.IGameExchangeMoneyService;
|
||||||
import com.ff.game.service.IGameService;
|
import com.ff.game.service.IGameService;
|
||||||
import com.ff.member.domain.Member;
|
import com.ff.member.domain.Member;
|
||||||
import com.ff.member.service.IMemberService;
|
import com.ff.member.service.IMemberService;
|
||||||
|
import com.ff.utils.CalculateDateDaysAgo;
|
||||||
|
import com.ff.utils.TimestampFromString;
|
||||||
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.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -36,10 +38,6 @@ import javax.annotation.Resource;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -368,7 +366,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
|
||||||
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.setStatus(1); // SUCCESS
|
exchangeMoney.setStatus(StatusType.SUCCESS.getValue()); // SUCCESS
|
||||||
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
|
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -396,7 +394,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
|
||||||
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.setStatus(1); // SUCCESS
|
exchangeMoney.setStatus(StatusType.SUCCESS.getValue()); // SUCCESS
|
||||||
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
|
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
|
||||||
} else {
|
} else {
|
||||||
throw new BaseException(MeiTianExchangeMoneyResponseDTO.TransferOut.get(exchangeMoneyResponse.getErrorCode()).getMessage());
|
throw new BaseException(MeiTianExchangeMoneyResponseDTO.TransferOut.get(exchangeMoneyResponse.getErrorCode()).getMessage());
|
||||||
|
@ -485,7 +483,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
|
||||||
|
|
||||||
boolean doSyncRecordByDate(BetRecordByTimeDTO betRecordByTimeDTO, int daysToSubtract) {
|
boolean doSyncRecordByDate(BetRecordByTimeDTO betRecordByTimeDTO, int daysToSubtract) {
|
||||||
|
|
||||||
String date = getDateStr(daysToSubtract);
|
String date = CalculateDateDaysAgo.getStr(daysToSubtract);
|
||||||
String configKey = GamePlatforms.MT.getCode() + ":lastSyncDate";
|
String configKey = GamePlatforms.MT.getCode() + ":lastSyncDate";
|
||||||
String syncDateStr = sysConfigServiceImpl.selectConfigByKey(configKey);
|
String syncDateStr = sysConfigServiceImpl.selectConfigByKey(configKey);
|
||||||
Map<String, Long> syncDateMap = new HashMap<>();
|
Map<String, Long> syncDateMap = new HashMap<>();
|
||||||
|
@ -750,7 +748,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
|
||||||
BigDecimal originPayoffAmount = new BigDecimal(dataBean.getIncome()); // 这个值是到手的
|
BigDecimal originPayoffAmount = new BigDecimal(dataBean.getIncome()); // 这个值是到手的
|
||||||
|
|
||||||
int compareResult = originPayoffAmount.compareTo(BigDecimal.ZERO);
|
int compareResult = originPayoffAmount.compareTo(BigDecimal.ZERO);
|
||||||
long gameTime = getTime(dataBean.getGameDate());
|
long gameTime = TimestampFromString.from(dataBean.getGameDate());
|
||||||
Platform platform = gamesDataBuildDTO.getPlatform();
|
Platform platform = gamesDataBuildDTO.getPlatform();
|
||||||
String systemCurrency = platform.getOurCurrency(dataBean.getCurrency());
|
String systemCurrency = platform.getOurCurrency(dataBean.getCurrency());
|
||||||
//数据构造
|
//数据构造
|
||||||
|
@ -782,30 +780,4 @@ public class MeiTianGameServiceImpl implements IGamesService {
|
||||||
gameBettingDetails.setCreateTime(DateUtils.getNowDate());
|
gameBettingDetails.setCreateTime(DateUtils.getNowDate());
|
||||||
return gameBettingDetails;
|
return gameBettingDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getTime(String date) {
|
|
||||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
try {
|
|
||||||
Date parse = simpleDateFormat.parse(date);
|
|
||||||
return parse.getTime();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
return System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getDate(int daysToSubtract) {
|
|
||||||
return LocalDate.now().minusDays(daysToSubtract); // 获取当前日期减去两天
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDateStr(int daysToSubtract) {
|
|
||||||
// 获取当前日期减去指定天数
|
|
||||||
LocalDate date = LocalDate.now().minusDays(daysToSubtract);
|
|
||||||
|
|
||||||
// 定义日期格式
|
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
||||||
|
|
||||||
// 返回格式化日期字符串
|
|
||||||
return date.format(formatter);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import lombok.NoArgsConstructor;
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建成员请求dto
|
* 查询用户信息
|
||||||
*
|
*
|
||||||
* @author shi
|
* @author shi
|
||||||
* @date 2024/10/22
|
* @date 2024/10/22
|
||||||
|
@ -19,7 +19,7 @@ public class MemberInfoRequestDTO extends GamesBaseRequestDTO {
|
||||||
/**
|
/**
|
||||||
* 账户
|
* 账户
|
||||||
*/
|
*/
|
||||||
private String accounts;
|
private String accounts;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
package com.ff.sports.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.system.service.ISysConfigService;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author shi
|
|
||||||
* @date 2025/02/10
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class FbAddress implements AddressSource {
|
|
||||||
|
|
||||||
public static final String API_BASE_URL = "fb.api.base.url";
|
|
||||||
@Resource
|
|
||||||
private ISysConfigService configService;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForestAddress getAddress(ForestRequest request) {
|
|
||||||
String apiBaseUrl = configService.selectConfigByKey(API_BASE_URL);
|
|
||||||
return new ForestAddress("https", apiBaseUrl, 443, "services");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
package com.ff.sports.fb;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author cengy
|
|
||||||
*/
|
|
||||||
public class A {
|
|
||||||
}
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.ff.sports.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;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档地址:https://doc.newsportspro.com/apidoc_data.html#%E5%85%A5%E5%8F%82
|
||||||
|
* @author shi
|
||||||
|
* @date 2025/02/10
|
||||||
|
*/
|
||||||
|
@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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package com.ff.sports.fb.client;
|
||||||
|
|
||||||
|
import com.dtflys.forest.annotation.*;
|
||||||
|
import com.ff.sports.fb.address.FBSportsAddress;
|
||||||
|
import com.ff.sports.fb.dto.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://doc.newsportspro.com/apidoc_data.html
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户金额转入到FB体育平台,支持两位小数,最小0.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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FB体育用拉取订单文件的方式同步订单数据,FB体育每5分钟生成一次订单文件,
|
||||||
|
* 通过此接口获取某一段时间内的文件ID列表,再通过文件ID获取具体订单数据
|
||||||
|
*/
|
||||||
|
@Post(url = "/api/v2/transfer/detail")
|
||||||
|
OrderFilesResponse orderFiles(@JSONBody OrderFilesRequest request,
|
||||||
|
@Header("sign") @Var("sign") String sign,
|
||||||
|
@Header("timestamp") @Var("timestamp") long timestamp,
|
||||||
|
@Header("merchantId") @Var("merchantId") String merchantId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.ff.sports.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.ff.sports.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;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.ff.sports.fb.dto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cengy
|
||||||
|
*/
|
||||||
|
public class Enums {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.ff.sports.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.ff.sports.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
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.ff.sports.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 "{}";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.ff.sports.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; //域名类型,1:API,2:PUSH,3:H5,4:PC,5:IMAGE , 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; // 权限值
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.ff.sports.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.ff.sports.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 Integer fileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.ff.sports.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 Integer fileId;
|
||||||
|
|
||||||
|
public String toJSON() {
|
||||||
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
|
map.put("fileId", fileId);
|
||||||
|
return JSON.toJSONString(map);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
package com.ff.sports.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; // 数据变更标记
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.ff.sports.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.ff.sports.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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.ff.sports.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.ff.sports.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;
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.ff.sports.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.ff.sports.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;
|
||||||
|
}
|
|
@ -0,0 +1,618 @@
|
||||||
|
package com.ff.sports.fb.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.generator.SnowflakeGenerator;
|
||||||
|
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.sign.Md5Utils;
|
||||||
|
import com.ff.base.utils.uuid.IdUtils;
|
||||||
|
import com.ff.game.api.IGamesService;
|
||||||
|
import com.ff.game.api.meitian.dto.MeiTianBetRecordResponseDTO;
|
||||||
|
import com.ff.game.api.meitian.dto.MeiTianGameDataDTO;
|
||||||
|
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.sports.fb.client.FBSportsClient;
|
||||||
|
import com.ff.sports.fb.dto.*;
|
||||||
|
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.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.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) {
|
||||||
|
|
||||||
|
Member member = memberService.selectMemberByGameAccount(requestDTO.getAccount());
|
||||||
|
String transactionId = GamePlatforms.FBSports.getCode() + IdUtils.simpleUUID();
|
||||||
|
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
|
||||||
|
GameExchangeMoney.builder()
|
||||||
|
.tenantKey(requestDTO.getTenantKey())
|
||||||
|
.orderId(requestDTO.getOrderId())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
|
||||||
|
//获取下一个自增id
|
||||||
|
GameExchangeMoney exchangeMoney = GameExchangeMoney
|
||||||
|
.builder()
|
||||||
|
.orderId(requestDTO.getOrderId())
|
||||||
|
.tenantKey(requestDTO.getTenantKey())
|
||||||
|
.quota(requestDTO.getQuota())
|
||||||
|
.balance(requestDTO.getAmount())
|
||||||
|
.exchangeType(requestDTO.getTransferType())
|
||||||
|
.currencyCode(requestDTO.getSystemCurrency())
|
||||||
|
.memberId(member.getId())
|
||||||
|
.transactionId(transactionId)
|
||||||
|
.platformCode(GamePlatforms.FBSports.getCode())
|
||||||
|
.build();
|
||||||
|
exchangeMoney.setCreateBy(Constants.SYSTEM);
|
||||||
|
//接口限制限制50字符
|
||||||
|
exchangeMoney.setTransactionId(transactionId);
|
||||||
|
// 转入
|
||||||
|
if (requestDTO.getTransferType().equals(TransferType.GAMES.getCode())) {
|
||||||
|
TransferInRequest request = new TransferInRequest();
|
||||||
|
request.setMerchantUserId(requestDTO.getAccount());
|
||||||
|
request.setAmount(requestDTO.getAmount());
|
||||||
|
request.setBusinessId(requestDTO.getOrderId());
|
||||||
|
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())) {
|
||||||
|
|
||||||
|
exchangeMoney.setBalance(response.getData());
|
||||||
|
BigDecimal transAmount = requestDTO.getAmount();
|
||||||
|
exchangeMoney.setCoinBefore(response.getData().subtract(transAmount));
|
||||||
|
exchangeMoney.setCoinAfter(response.getData());
|
||||||
|
exchangeMoney.setCurrencyBefore(response.getData().subtract(transAmount));
|
||||||
|
exchangeMoney.setCurrencyAfter(response.getData());
|
||||||
|
exchangeMoney.setStatus(StatusType.SUCCESS.getValue()); // SUCCESS
|
||||||
|
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
|
||||||
|
} else {
|
||||||
|
throw new ApiException(ErrorCode.Transfer_In_Failure.getCode());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 获取第三方钱包余额
|
||||||
|
MemberInfoRequestDTO memberInfoRequestDTO = MemberInfoRequestDTO.builder()
|
||||||
|
.accounts(member.getGameAccount())
|
||||||
|
.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.getOrderId());
|
||||||
|
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())) {
|
||||||
|
//更新数据
|
||||||
|
exchangeMoney.setBalance(response.getData());
|
||||||
|
BigDecimal transAmount = balance;
|
||||||
|
exchangeMoney.setCoinBefore(response.getData().add(transAmount));
|
||||||
|
exchangeMoney.setCoinAfter(response.getData());
|
||||||
|
exchangeMoney.setCurrencyBefore(response.getData().add(transAmount));
|
||||||
|
exchangeMoney.setCurrencyAfter(response.getData());
|
||||||
|
exchangeMoney.setStatus(StatusType.SUCCESS.getValue()); // SUCCESS
|
||||||
|
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
|
||||||
|
} else {
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无重定向登录
|
||||||
|
*
|
||||||
|
* @param requestDTO 游戏登录
|
||||||
|
* @return {@link String }
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String loginWithoutRedirect(GamesLogin requestDTO) {
|
||||||
|
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 = 1904452832756013817L;
|
||||||
|
/**
|
||||||
|
* 获取游戏列表
|
||||||
|
*
|
||||||
|
* @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.setSortNo(1);
|
||||||
|
//game.setPlatformId(gamePlatform.getId());
|
||||||
|
game.setPlatformCode(platform.getPlatformCode());
|
||||||
|
game.setPlatformType(PlatformType.GAME_HALL.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 Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO requestDTO) {
|
||||||
|
|
||||||
|
GameExchangeMoney gameExchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(requestDTO.getGameExchangeMoneyId());
|
||||||
|
if (null == gameExchangeMoney) {
|
||||||
|
throw new ApiException(ErrorCode.Transfer_Not_Exist.getCode());
|
||||||
|
}
|
||||||
|
if (Objects.equals(gameExchangeMoney.getStatus(), StatusType.SUCCESS.getValue())) {
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
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())) {
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按时间获取投注记录
|
||||||
|
*
|
||||||
|
* @param betRecordByTimeDTO 按时间dto投注记录
|
||||||
|
* @return {@link Boolean }
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
|
||||||
|
return doSyncRecordByRecordID(betRecordByTimeDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean doSyncRecordByRecordID(BetRecordByTimeDTO betRecordByTimeDTO) {
|
||||||
|
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean doSyncRecordByDate(BetRecordByTimeDTO betRecordByTimeDTO, int daysToSubtract) {
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按历史时间获取投注记录
|
||||||
|
*
|
||||||
|
* @param betRecordByTimeDTO 按时间dto投注记录
|
||||||
|
* @return {@link Boolean }
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
|
||||||
|
doSyncRecordByDate(betRecordByTimeDTO, 0);
|
||||||
|
doSyncRecordByDate(betRecordByTimeDTO, 1); // yesterday
|
||||||
|
|
||||||
|
return 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) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 强制会员从游戏注销
|
||||||
|
*
|
||||||
|
* @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 获取自由旋转dashflow请求dto
|
||||||
|
* @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 recordResponse 投注记录
|
||||||
|
*/
|
||||||
|
private void batchInsert(MeiTianBetRecordResponseDTO recordResponse, BetRecordByTimeDTO betRecordByTimeDTO) {
|
||||||
|
List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
|
||||||
|
List<String> wagersIds = new ArrayList<>();
|
||||||
|
//数据组装
|
||||||
|
List<MeiTianBetRecordResponseDTO.DataBean> dataList = recordResponse.getDataList();
|
||||||
|
if (CollectionUtils.isEmpty(dataList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//数据转化
|
||||||
|
for (MeiTianBetRecordResponseDTO.DataBean 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.getRowID());
|
||||||
|
}
|
||||||
|
if (!CollectionUtils.isEmpty(gameBettingDetails)) {
|
||||||
|
//查询重复数据id
|
||||||
|
List<String> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds, GamePlatforms.MT.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) {
|
||||||
|
|
||||||
|
//转化类
|
||||||
|
MeiTianBetRecordResponseDTO.DataBean dataBean = (MeiTianBetRecordResponseDTO.DataBean) gamesDataBuildDTO.getData();
|
||||||
|
// GameSecretKeyCurrencyDTO gameSecretKey =
|
||||||
|
// gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
|
||||||
|
// .currency(dataBean.getCurrency())
|
||||||
|
// .platformCode(GamePlatforms.MT.getCode()).build());
|
||||||
|
|
||||||
|
|
||||||
|
Member member = memberService.selectMemberByGameAccount(dataBean.getPlayerName());
|
||||||
|
if (ObjectUtils.isEmpty(member)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<MeiTianGameDataDTO> gameDatas = redisCache.getCacheList(CacheConstants.MeiTian_GAMES);
|
||||||
|
Map<String, MeiTianGameDataDTO> dataDTOMap = gameDatas.stream().collect(Collectors.toMap(MeiTianGameDataDTO::getGameId, e -> e));
|
||||||
|
MeiTianGameDataDTO gamesDataDTO = dataDTOMap.get(dataBean.getGameCode());
|
||||||
|
BigDecimal originPayoffAmount = new BigDecimal(dataBean.getIncome()); // 这个值是到手的
|
||||||
|
|
||||||
|
int compareResult = originPayoffAmount.compareTo(BigDecimal.ZERO);
|
||||||
|
long gameTime = TimestampFromString.from(dataBean.getGameDate());
|
||||||
|
Platform platform = gamesDataBuildDTO.getPlatform();
|
||||||
|
String systemCurrency = platform.getOurCurrency(dataBean.getCurrency());
|
||||||
|
//数据构造
|
||||||
|
GameBettingDetails gameBettingDetails = GameBettingDetails.builder()
|
||||||
|
.tenantKey(member.getTenantKey())
|
||||||
|
//保存我们的币种id
|
||||||
|
.currencyCode(systemCurrency)
|
||||||
|
.memberId(member.getId())
|
||||||
|
.gameCode(dataBean.getGameCode())
|
||||||
|
.gameType(MeiTianGameType.findSystemByCode(Integer.parseInt(dataBean.getGameType())))
|
||||||
|
.platformCode(GamePlatforms.MT.getCode())
|
||||||
|
.gameId(gamesDataDTO.getSystemGameId())
|
||||||
|
.gameName(gamesDataDTO.getCnName())
|
||||||
|
.gameStatus(compareResult > 0 ? GameStatus.WIN.getCode() : compareResult < 0 ? GameStatus.FAIL.getCode() : GameStatus.FLAT.getCode())
|
||||||
|
.gameStatusType(1) // 一般下注
|
||||||
|
.gameCurrencyCode(dataBean.getCurrency())
|
||||||
|
.account(dataBean.getPlayerName())
|
||||||
|
.wagersId(dataBean.getRowID())
|
||||||
|
.wagersTime(gameTime)
|
||||||
|
.betAmount(new BigDecimal(dataBean.getBetAmount()))
|
||||||
|
.payoffTime(gameTime)
|
||||||
|
.payoffAmount(originPayoffAmount.abs())
|
||||||
|
.settlementTime(gameTime)
|
||||||
|
.turnover(new BigDecimal(dataBean.getCommissionable()))
|
||||||
|
.orderNo(dataBean.getRowID())
|
||||||
|
.settlementStatus(SettlementStatusEnum.COMPLETED.getCode())
|
||||||
|
.build();
|
||||||
|
gameBettingDetails.setCreateBy(Constants.SYSTEM);
|
||||||
|
gameBettingDetails.setCreateTime(DateUtils.getNowDate());
|
||||||
|
return gameBettingDetails;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.ff.utils;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cengy
|
||||||
|
*/
|
||||||
|
public class CalculateDateDaysAgo {
|
||||||
|
|
||||||
|
public static LocalDate get(int daysToSubtract) {
|
||||||
|
return LocalDate.now().minusDays(daysToSubtract);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStr(int daysToSubtract) {
|
||||||
|
// 获取当前日期减去指定天数
|
||||||
|
LocalDate date = get(daysToSubtract);
|
||||||
|
|
||||||
|
// 定义日期格式
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
|
||||||
|
// 返回格式化日期字符串
|
||||||
|
return date.format(formatter);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.ff.utils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cengy
|
||||||
|
*/
|
||||||
|
public class SortByAttributeNameASC {
|
||||||
|
public static String get(Object o) {
|
||||||
|
// Create a map to store field names and values
|
||||||
|
Map<String, Object> fieldMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
// Get all fields of the class
|
||||||
|
Field[] fields = o.getClass().getDeclaredFields();
|
||||||
|
|
||||||
|
// Sort field names
|
||||||
|
Arrays.sort(fields, (f1, f2) -> f1.getName().compareTo(f2.getName()));
|
||||||
|
|
||||||
|
// Fill the map with sorted fields and their values
|
||||||
|
for (Field field : fields) {
|
||||||
|
field.setAccessible(true); // Make private fields accessible
|
||||||
|
Object value = null;
|
||||||
|
try {
|
||||||
|
value = field.get(o);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
fieldMap.put(field.getName(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return JSON.toJSONString(fieldMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.ff.utils;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cengy
|
||||||
|
*/
|
||||||
|
public class TimestampFromString {
|
||||||
|
|
||||||
|
public static final String PATTERN_DATE = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
public static Long from(String date) {
|
||||||
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE);
|
||||||
|
try {
|
||||||
|
Date parse = simpleDateFormat.parse(date);
|
||||||
|
return parse.getTime();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<resultMap type="Game" id="GameResult">
|
<resultMap type="Game" id="GameResult">
|
||||||
<result property="id" column="id" />
|
<result property="id" column="id" />
|
||||||
<result property="sortNo" column="sort_no" />
|
<result property="sortNo" column="sort_no" />
|
||||||
<result property="platformId" column="platform_id" />
|
|
||||||
<result property="gameCode" column="game_code" />
|
<result property="gameCode" column="game_code" />
|
||||||
<result property="ingress" column="ingress" />
|
<result property="ingress" column="ingress" />
|
||||||
<result property="gameSourceType" column="game_source_type" />
|
<result property="gameSourceType" column="game_source_type" />
|
||||||
|
@ -16,6 +15,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<result property="freespin" column="freespin" />
|
<result property="freespin" column="freespin" />
|
||||||
<result property="demoStatus" column="demo_status" />
|
<result property="demoStatus" column="demo_status" />
|
||||||
<result property="stopStatus" column="stop_status" />
|
<result property="stopStatus" column="stop_status" />
|
||||||
|
<result property="platformCode" column="platform_code" />
|
||||||
|
<result property="platformType" column="platform_type" />
|
||||||
<result property="createBy" column="create_by" />
|
<result property="createBy" column="create_by" />
|
||||||
<result property="createTime" column="create_time" />
|
<result property="createTime" column="create_time" />
|
||||||
<result property="updateBy" column="update_by" />
|
<result property="updateBy" column="update_by" />
|
||||||
|
@ -23,7 +24,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectGameVo">
|
<sql id="selectGameVo">
|
||||||
select id, sort_no, platform_id, game_code,ingress, game_source_type, game_name, freespin, demo_status, stop_status, create_by, create_time, update_by, update_time from ff_game
|
select * from ff_game
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,7 +34,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<include refid="selectGameVo"/>
|
<include refid="selectGameVo"/>
|
||||||
<where>
|
<where>
|
||||||
<if test="sortNo != null "> and sort_no = #{sortNo}</if>
|
<if test="sortNo != null "> and sort_no = #{sortNo}</if>
|
||||||
<if test="platformId != null "> and platform_id = #{platformId}</if>
|
|
||||||
<if test="gameCode != null "> and game_code = #{gameCode}</if>
|
<if test="gameCode != null "> and game_code = #{gameCode}</if>
|
||||||
<if test="ingress != null "> and ingress = #{ingress}</if>
|
<if test="ingress != null "> and ingress = #{ingress}</if>
|
||||||
<if test="gameSourceType != null "> and game_source_type = #{gameSourceType}</if>
|
<if test="gameSourceType != null "> and game_source_type = #{gameSourceType}</if>
|
||||||
|
@ -48,40 +48,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectGameDTOList" parameterType="com.ff.game.dto.GameDTO" resultMap="GameResult">
|
<select id="selectGameDTOList" parameterType="com.ff.game.dto.GameDTO" resultMap="GameResult">
|
||||||
select g.id,
|
<include refid="selectGameVo"/>
|
||||||
g.sort_no,
|
|
||||||
g.platform_id,
|
|
||||||
g.game_code,
|
|
||||||
g.ingress,
|
|
||||||
g.game_source_type,
|
|
||||||
g.game_name,
|
|
||||||
g.freespin,
|
|
||||||
g.demo_status,
|
|
||||||
g.stop_status,
|
|
||||||
g.create_by,
|
|
||||||
g.create_time,
|
|
||||||
g.update_by,
|
|
||||||
g.update_time
|
|
||||||
from ff_game g
|
|
||||||
inner join ff_game_platform p on g.platform_id = p.id
|
|
||||||
|
|
||||||
|
|
||||||
<where>
|
<where>
|
||||||
<if test="sortNo != null "> and g.sort_no = #{sortNo}</if>
|
<if test="sortNo != null "> and sort_no = #{sortNo}</if>
|
||||||
<if test="platformId != null "> and g.platform_id = #{platformId}</if>
|
<if test="gameCode != null "> and game_code = #{gameCode}</if>
|
||||||
<if test="gameCode != null "> and g.game_code = #{gameCode}</if>
|
<if test="ingress != null "> and ingress = #{ingress}</if>
|
||||||
<if test="ingress != null "> and g.ingress = #{ingress}</if>
|
<if test="gameSourceType != null "> and game_source_type = #{gameSourceType}</if>
|
||||||
<if test="gameSourceType != null "> and g.game_source_type = #{gameSourceType}</if>
|
|
||||||
<if test="gameName != null and gameName != ''"> and game_name like concat('%', #{gameName}, '%')</if>
|
<if test="gameName != null and gameName != ''"> and game_name like concat('%', #{gameName}, '%')</if>
|
||||||
<if test="freespin != null "> and g.freespin = #{freespin}</if>
|
<if test="freespin != null "> and freespin = #{freespin}</if>
|
||||||
<if test="demoStatus != null "> and g.demo_status = #{demoStatus}</if>
|
<if test="demoStatus != null "> and demo_status = #{demoStatus}</if>
|
||||||
<if test="stopStatus != null "> and g.stop_status = #{stopStatus}</if>
|
<if test="stopStatus != null "> and stop_status = #{stopStatus}</if>
|
||||||
<if test="platformCodes != null and platformCodes.size()>0"> and p.platform_code in
|
<if test="platformCode != null "> and platform_code = #{platformCode}</if>
|
||||||
<foreach collection="platforms" item="item" index="index" open="(" close=")" separator=",">
|
<if test="platformType != null "> and platform_type = #{platformType}</if>
|
||||||
#{item}
|
|
||||||
</foreach>
|
|
||||||
</if>
|
|
||||||
<if test="platformCode != null and platformCode != ''"> and p.platform_code = #{platformCode}</if>
|
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
@ -112,7 +91,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=","> <if test="id != null">#{id},</if>
|
<trim prefix="values (" suffix=")" suffixOverrides=","> <if test="id != null">#{id},</if>
|
||||||
<if test="sortNo != null">#{sortNo},</if>
|
<if test="sortNo != null">#{sortNo},</if>
|
||||||
<if test="platformId != null">#{platformId},</if>
|
|
||||||
<if test="gameCode != null">#{gameCode},</if>
|
<if test="gameCode != null">#{gameCode},</if>
|
||||||
<if test="ingress != null">#{ingress},</if>
|
<if test="ingress != null">#{ingress},</if>
|
||||||
<if test="gameSourceType != null">#{gameSourceType},</if>
|
<if test="gameSourceType != null">#{gameSourceType},</if>
|
||||||
|
@ -131,7 +109,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
update ff_game
|
update ff_game
|
||||||
<trim prefix="SET" suffixOverrides=",">
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
<if test="sortNo != null">sort_no = #{sortNo},</if>
|
<if test="sortNo != null">sort_no = #{sortNo},</if>
|
||||||
<if test="platformId != null">platform_id = #{platformId},</if>
|
|
||||||
<if test="gameCode != null">game_code = #{gameCode},</if>
|
<if test="gameCode != null">game_code = #{gameCode},</if>
|
||||||
<if test="ingress != null">ingress = #{ingress},</if>
|
<if test="ingress != null">ingress = #{ingress},</if>
|
||||||
<if test="gameSourceType != null">game_source_type = #{gameSourceType},</if>
|
<if test="gameSourceType != null">game_source_type = #{gameSourceType},</if>
|
||||||
|
@ -192,8 +169,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
g.ingress,
|
g.ingress,
|
||||||
gp.platform_type
|
gp.platform_type
|
||||||
from ff_game g
|
from ff_game g
|
||||||
inner join ff_game_platform gp on g.platform_id=gp.id
|
where g.stop_status=1
|
||||||
where gp.stop_status=1 and g.stop_status=1
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue