feat(fb-sports): 实现 FB 体育数据对接
- 新增 FB 体育类型枚举类 FBSportsType - 实现 FB 体育客户端接口,包括获取 token、订单文件列表和订单数据- 重构 FBSportsServiceImpl 类,支持按时间和历史时间获取投注记录 - 优化数据处理逻辑,实现批量插入功能 -移除不必要的定时任务配置main-meitian
parent
b087305ba1
commit
8ec1afd875
|
@ -0,0 +1,60 @@
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -746,8 +746,8 @@ public class MeiTianGameServiceImpl implements IGamesService {
|
|||
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);
|
||||
BigDecimal betAmount = new BigDecimal(dataBean.getBetAmount());
|
||||
int compareResult = originPayoffAmount.compareTo(betAmount);
|
||||
long gameTime = TimestampFromString.from(dataBean.getGameDate());
|
||||
Platform platform = gamesDataBuildDTO.getPlatform();
|
||||
String systemCurrency = platform.getOurCurrency(dataBean.getCurrency());
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
package com.ff.quartz.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效)
|
||||
*
|
||||
* @author ff
|
||||
*/
|
||||
@Configuration
|
||||
public class ScheduleConfig
|
||||
{
|
||||
@Bean
|
||||
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource)
|
||||
{
|
||||
SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
factory.setDataSource(dataSource);
|
||||
|
||||
// quartz参数
|
||||
Properties prop = new Properties();
|
||||
prop.put("org.quartz.scheduler.instanceName", "ffScheduler");
|
||||
prop.put("org.quartz.scheduler.instanceId", "AUTO");
|
||||
// 线程池配置
|
||||
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
|
||||
prop.put("org.quartz.threadPool.threadCount", "20");
|
||||
prop.put("org.quartz.threadPool.threadPriority", "5");
|
||||
// JobStore配置
|
||||
prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
|
||||
// 集群配置
|
||||
prop.put("org.quartz.jobStore.isClustered", "true");
|
||||
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
|
||||
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "10");
|
||||
prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
|
||||
|
||||
// sqlserver 启用
|
||||
// prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
|
||||
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
|
||||
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
|
||||
factory.setQuartzProperties(prop);
|
||||
|
||||
factory.setSchedulerName("ffScheduler");
|
||||
// 延时启动
|
||||
factory.setStartupDelay(1);
|
||||
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
|
||||
// 可选,QuartzScheduler
|
||||
// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
|
||||
factory.setOverwriteExistingJobs(true);
|
||||
// 设置自动启动,默认为true
|
||||
factory.setAutoStartup(true);
|
||||
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
//package com.ff.quartz.config;
|
||||
//
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
//import javax.sql.DataSource;
|
||||
//import java.util.Properties;
|
||||
//
|
||||
///**
|
||||
// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效)
|
||||
// *
|
||||
// * @author ff
|
||||
// */
|
||||
//@Configuration
|
||||
//public class ScheduleConfig
|
||||
//{
|
||||
// @Bean
|
||||
// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource)
|
||||
// {
|
||||
// SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
// factory.setDataSource(dataSource);
|
||||
//
|
||||
// // quartz参数
|
||||
// Properties prop = new Properties();
|
||||
// prop.put("org.quartz.scheduler.instanceName", "ffScheduler");
|
||||
// prop.put("org.quartz.scheduler.instanceId", "AUTO");
|
||||
// // 线程池配置
|
||||
// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
|
||||
// prop.put("org.quartz.threadPool.threadCount", "20");
|
||||
// prop.put("org.quartz.threadPool.threadPriority", "5");
|
||||
// // JobStore配置
|
||||
// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
|
||||
// // 集群配置
|
||||
// prop.put("org.quartz.jobStore.isClustered", "true");
|
||||
// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
|
||||
// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "10");
|
||||
// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
|
||||
//
|
||||
// // sqlserver 启用
|
||||
// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
|
||||
// prop.put("org.quartz.jobStore.misfireThreshold", "12000");
|
||||
// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
|
||||
// factory.setQuartzProperties(prop);
|
||||
//
|
||||
// factory.setSchedulerName("ffScheduler");
|
||||
// // 延时启动
|
||||
// factory.setStartupDelay(1);
|
||||
// factory.setApplicationContextSchedulerContextKey("applicationContextKey");
|
||||
// // 可选,QuartzScheduler
|
||||
// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
|
||||
// factory.setOverwriteExistingJobs(true);
|
||||
// // 设置自动启动,默认为true
|
||||
// factory.setAutoStartup(true);
|
||||
//
|
||||
// return factory;
|
||||
// }
|
||||
//}
|
||||
|
|
|
@ -11,9 +11,9 @@ import javax.annotation.Resource;
|
|||
|
||||
|
||||
/**
|
||||
* 文档地址:https://doc.newsportspro.com/apidoc_data.html#%E5%85%A5%E5%8F%82
|
||||
* @author shi
|
||||
* @date 2025/02/10
|
||||
* <a href="https://doc.newsportspro.com/apidoc_data.html#%E5%85%A5%E5%8F%82">对接文档地址</a>
|
||||
*
|
||||
* @author cengy
|
||||
*/
|
||||
@Component
|
||||
public class FBSportsAddress implements AddressSource {
|
||||
|
|
|
@ -5,7 +5,8 @@ import com.ff.sports.fb.address.FBSportsAddress;
|
|||
import com.ff.sports.fb.dto.*;
|
||||
|
||||
/**
|
||||
* https://doc.newsportspro.com/apidoc_data.html
|
||||
* <a href="https://doc.newsportspro.com/apidoc_data.html">数据接口文档</a><br/>
|
||||
* <a href="https://doc.newsportspro.com/h5_pc_doc.html">网页接入文档</a>
|
||||
*
|
||||
* @author cengy
|
||||
*/
|
||||
|
@ -68,10 +69,34 @@ public interface FBSportsClient {
|
|||
* FB体育用拉取订单文件的方式同步订单数据,FB体育每5分钟生成一次订单文件,
|
||||
* 通过此接口获取某一段时间内的文件ID列表,再通过文件ID获取具体订单数据
|
||||
*/
|
||||
@Post(url = "/api/v2/transfer/detail")
|
||||
@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);
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户app端鉴权token和相关服务url,获取到的token用于app调用接口鉴权
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
|
|
@ -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.Map;
|
||||
|
||||
/**
|
||||
* @author cengy
|
||||
*/
|
||||
@Data
|
||||
public class GetTokenRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String merchantUserId;
|
||||
// 平台类型,pc,h5, 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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.ff.sports.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; // 域名集合
|
||||
}
|
||||
}
|
|
@ -29,5 +29,13 @@ public class OrderFilesRequest implements Serializable {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public class OrderFilesResponse implements Serializable {
|
|||
@Data
|
||||
public static class FileId implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Integer fileId;
|
||||
private Long fileId;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ public class OrderInfoRequest implements Serializable {
|
|||
/**
|
||||
* 文件Id,需要从/order/file/ids接口获取到
|
||||
*/
|
||||
private Integer fileId;
|
||||
private Long fileId;
|
||||
|
||||
public String toJSON() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
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;
|
||||
|
@ -9,11 +8,10 @@ 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.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;
|
||||
|
@ -33,7 +31,10 @@ import org.springframework.util.ObjectUtils;
|
|||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
|
@ -285,7 +286,50 @@ public class FBSportsServiceImpl implements IGamesService {
|
|||
*/
|
||||
@Override
|
||||
public String loginWithoutRedirect(GamesLogin requestDTO) {
|
||||
GetUrlRequest request = new GetUrlRequest();
|
||||
GetTokenRequest request = new GetTokenRequest();
|
||||
request.setMerchantUserId(requestDTO.getAccount());
|
||||
request.setPlatForm(/*requestDTO.getPlatform()*/ "mobile"); // pc,h5, 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,
|
||||
|
@ -314,10 +358,12 @@ public class FBSportsServiceImpl implements IGamesService {
|
|||
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;
|
||||
|
||||
/**
|
||||
* 获取游戏列表
|
||||
*
|
||||
|
@ -405,35 +451,123 @@ public class FBSportsServiceImpl implements IGamesService {
|
|||
/**
|
||||
* 按时间获取投注记录
|
||||
*
|
||||
* @param betRecordByTimeDTO 按时间dto投注记录
|
||||
* @param requestDTO 按时间dto投注记录
|
||||
* @return {@link Boolean }
|
||||
*/
|
||||
@Override
|
||||
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
|
||||
return doSyncRecordByRecordID(betRecordByTimeDTO);
|
||||
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;
|
||||
}
|
||||
|
||||
boolean doSyncRecordByRecordID(BetRecordByTimeDTO betRecordByTimeDTO) {
|
||||
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
|
||||
);
|
||||
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
boolean doSyncRecordByDate(BetRecordByTimeDTO betRecordByTimeDTO, int daysToSubtract) {
|
||||
return Boolean.FALSE;
|
||||
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 betRecordByTimeDTO 按时间dto投注记录
|
||||
* @param requestDTO 按时间dto投注记录
|
||||
* @return {@link Boolean }
|
||||
*/
|
||||
@Override
|
||||
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
|
||||
doSyncRecordByDate(betRecordByTimeDTO, 0);
|
||||
doSyncRecordByDate(betRecordByTimeDTO, 1); // yesterday
|
||||
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO requestDTO) {
|
||||
Long lend = requestDTO.getEndTime();
|
||||
Long lstart = requestDTO.getStartTime();
|
||||
//betRecordByTimeDTO.setStartTime(lstart);
|
||||
//betRecordByTimeDTO.setEndTime(lend);
|
||||
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -456,8 +590,7 @@ public class FBSportsServiceImpl implements IGamesService {
|
|||
*/
|
||||
@Override
|
||||
public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) {
|
||||
|
||||
return null;
|
||||
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -516,23 +649,22 @@ public class FBSportsServiceImpl implements IGamesService {
|
|||
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量插入
|
||||
*
|
||||
* @param recordResponse 投注记录
|
||||
* @param settledOrderList 投注记录
|
||||
*/
|
||||
private void batchInsert(MeiTianBetRecordResponseDTO recordResponse, BetRecordByTimeDTO betRecordByTimeDTO) {
|
||||
private void batchInsert(List<OrderInfoResponse.OrderDTO> settledOrderList, BetRecordByTimeDTO betRecordByTimeDTO) {
|
||||
List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
|
||||
List<String> wagersIds = new ArrayList<>();
|
||||
//数据组装
|
||||
List<MeiTianBetRecordResponseDTO.DataBean> dataList = recordResponse.getDataList();
|
||||
List<OrderInfoResponse.OrderDTO> dataList = settledOrderList;
|
||||
if (CollectionUtils.isEmpty(dataList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//数据转化
|
||||
for (MeiTianBetRecordResponseDTO.DataBean dataBean : dataList) {
|
||||
for (OrderInfoResponse.OrderDTO dataBean : dataList) {
|
||||
GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder()
|
||||
.platform(betRecordByTimeDTO.getVendor())
|
||||
.data(dataBean).build());
|
||||
|
@ -540,20 +672,21 @@ public class FBSportsServiceImpl implements IGamesService {
|
|||
bettingDetails.setId(IdUtil.getSnowflakeNextId());
|
||||
gameBettingDetails.add(bettingDetails);
|
||||
}
|
||||
wagersIds.add(dataBean.getRowID());
|
||||
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)) {
|
||||
//查询重复数据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);
|
||||
}
|
||||
gameBettingDetailsService.batchInsert(gameBettingDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -566,49 +699,44 @@ public class FBSportsServiceImpl implements IGamesService {
|
|||
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());
|
||||
OrderInfoResponse.OrderDTO dataBean = (OrderInfoResponse.OrderDTO) gamesDataBuildDTO.getData();
|
||||
Member member = memberService.selectMemberByGameAccount(dataBean.getMerchantUserId());
|
||||
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()); // 这个值是到手的
|
||||
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(BigDecimal.ZERO);
|
||||
long gameTime = TimestampFromString.from(dataBean.getGameDate());
|
||||
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());
|
||||
String systemCurrency = platform.getOurCurrency(dataBean.getCurrency().toString());
|
||||
//数据构造
|
||||
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())
|
||||
.gameCode(game.getGameCode())
|
||||
.gameType(8) // 体育
|
||||
.platformCode(GamePlatforms.FBSports.getCode())
|
||||
.gameId(game.getId())
|
||||
.gameName(game.getGameName())
|
||||
.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)
|
||||
.gameCurrencyCode(dataBean.getCurrency().toString())
|
||||
.account(dataBean.getMerchantUserId())
|
||||
.wagersId(dataBean.getId())
|
||||
.wagersTime(createTime)
|
||||
.betAmount(betAmount)
|
||||
.payoffTime(payoffTime)
|
||||
.payoffAmount(originPayoffAmount.abs())
|
||||
.settlementTime(gameTime)
|
||||
.turnover(new BigDecimal(dataBean.getCommissionable()))
|
||||
.orderNo(dataBean.getRowID())
|
||||
.settlementTime(payoffTime)
|
||||
.turnover(betAmount)
|
||||
.orderNo(dataBean.getId())
|
||||
.settlementStatus(SettlementStatusEnum.COMPLETED.getCode())
|
||||
.build();
|
||||
gameBettingDetails.setCreateBy(Constants.SYSTEM);
|
||||
|
|
|
@ -20,4 +20,8 @@ public class TimestampFromString {
|
|||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
public static Long to(String timestamp) {
|
||||
return Long.parseLong(timestamp);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue