feat(game): 更新 DG 平台相关功能

- 修改会员游戏账号生成逻辑,支持 DG 平台
- 实现 DG 平台的踢人和踢出所有人的功能
- 更新 DG 平台的注单记录获取逻辑
- 优化 DG 客户端的接口调用
main-dg
shi 2025-03-27 14:36:05 +08:00
parent 41a9e3dee4
commit d293f638bf
9 changed files with 190 additions and 49 deletions

View File

@ -29,4 +29,23 @@ public class RandomGeneratorUtils {
return sb.toString(); return sb.toString();
} }
/**
* 5-8
*
* @return {@link String }
*/
public static String generateRandomAccountUpper() {
int length = 5 + RANDOM.nextInt(4);
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
char randomChar = CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()));
// 转换为大写字母或保持数字
if (Character.isLetter(randomChar)) {
sb.append(Character.toUpperCase(randomChar));
} else {
sb.append(randomChar); // 保持数字
}
}
return sb.toString();
}
} }

View File

@ -104,7 +104,7 @@ public class ApiMemberController extends BaseController {
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode()); ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
String gameAccount = StringUtils.addSuffix(memberService.getMemberGameAccount(), tenantSecretKey.getTenantSn()); String gameAccount = StringUtils.addSuffix(memberService.getMemberGameAccount(memberCreateApiRequest.getPlatformCode()), tenantSecretKey.getTenantSn());
// 获取用户信息 // 获取用户信息

View File

@ -22,7 +22,6 @@ public class MemberCreateApiRequest implements Serializable{
@NotBlank(message = "account不能为空") @NotBlank(message = "account不能为空")
@Length(max = 64, message = "account长度不能超过64个字符") @Length(max = 64, message = "account长度不能超过64个字符")
@Pattern(regexp = "^[a-z0-9]+$", message = "account只能包含小写字母和数字")
private String account; private String account;
/** 平台编码 */ /** 平台编码 */

View File

@ -45,14 +45,6 @@ public interface DGClient {
@Post("/v2/api/login") @Post("/v2/api/login")
DGLoginWithoutRedirectResponse loginWithoutRedirect(@JSONBody Map<String, Object> params, @Header Map<String, Object> header); DGLoginWithoutRedirectResponse loginWithoutRedirect(@JSONBody Map<String, Object> params, @Header Map<String, Object> header);
/**
*
*
* @param params
* @return {@link JILIGamesDTO }
*/
@Post("/getGameList")
XKGamesDTO getGameList(@JSONBody Map<String, Object> params);
/** /**
* id * id
@ -87,19 +79,28 @@ public interface DGClient {
* *
* *
* @param params * @param params
* @return {@link JILIKickMemberDTO } * @return {@link DGResponse }
*/ */
@Post("/kickMember") @Post("/v2/api/offline")
XKKickMemberDTO kickMember(@JSONBody Map<String, Object> params); DGResponse kickMember(@JSONBody Map<String, Object> params, @Header Map<String, Object> header);
@Post("/v2/api/offlineAll")
DGResponse kickMemberAll(@JSONBody Map<String, Object> params, @Header Map<String, Object> header);
/** /**
* * 线
* *
* @param params * @param params
* @return {@link JILIKickMemberAllDTO } * @return {@link DGUserListResponseDTO }
*/ */
@Get("/kickMemberAll") @Post(url ="/v2/api/online",
XKKickMemberAllDTO kickMemberAll(@JSONBody Map<String, Object> params); headers = {
"Content-type: application/x-www-form-urlencoded"
})
DGUserListResponseDTO memberOnlines(@Header Map<String, Object> params);
} }

View File

@ -25,8 +25,8 @@ public class DGBetRecordResponseDTO {
private String msg; private String msg;
/** 注单报告 */ /** 注单报告 */
@JsonProperty("report") @JsonProperty("list")
private List<ReportDTO> report; private List<ReportDTO> list;
/** /**
* *

View File

@ -0,0 +1,70 @@
package com.ff.game.api.dg.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
*
*
* @author shi
* @date 2025/03/27
*/
@Data
public class DGUserListResponseDTO {
/**
* ID
*/
@JsonProperty("codeId")
private int codeId;
/**
*
*/
@JsonProperty("msg")
private String msg;
/** 用户列表 */
@JsonProperty("list")
private List<UserDTO> list;
/**
*
*/
@Data
public static class UserDTO {
/** 用户名 */
@JsonProperty("username")
private String username;
/** 昵称 */
@JsonProperty("nickname")
private String nickname;
/** 币种名称 */
@JsonProperty("currencyName")
private String currencyName;
/** 用户IP */
@JsonProperty("ip")
private String ip;
/** 用户设备 */
@JsonProperty("device")
private String device;
/** 登录时间 */
@JsonProperty("login")
private String login;
/** 会员ID */
@JsonProperty("memberId")
private Long memberId;
/** 用户余额 */
@JsonProperty("balance")
private Double balance;
}
}

View File

@ -280,7 +280,7 @@ public class GamesDGServiceImpl implements IGamesService {
.build()); .build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = GamePlatforms.DG.getCode() + IdUtils.simpleUUID(); String transactionId = GamePlatforms.DG.getInfo() + IdUtils.simpleUUID();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList( List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder() GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey()) .tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
@ -300,7 +300,7 @@ public class GamesDGServiceImpl implements IGamesService {
.currencyCode(currencyDTO.getSystemCurrency()) .currencyCode(currencyDTO.getSystemCurrency())
.memberId(member.getId()) .memberId(member.getId())
.transactionId(transactionId) .transactionId(transactionId)
.platformCode(GamePlatforms.DG.getCode()) .platformCode(GamePlatforms.DG.getInfo())
.build(); .build();
exchangeMoney.setCreateBy(Constants.SYSTEM); exchangeMoney.setCreateBy(Constants.SYSTEM);
@ -369,7 +369,6 @@ public class GamesDGServiceImpl implements IGamesService {
Map<String, Object> key = this.getKey(betRecordByTimeDTO); Map<String, Object> key = this.getKey(betRecordByTimeDTO);
DGBetRecordResponseDTO betRecordByTime = DGClient.getBetRecordByTime(key); DGBetRecordResponseDTO betRecordByTime = DGClient.getBetRecordByTime(key);
//判断是否获取成功
if (this.getIsSuccess(betRecordByTime.getCodeId())) { if (this.getIsSuccess(betRecordByTime.getCodeId())) {
this.batchInsert(betRecordByTime,betRecordByTimeDTO); this.batchInsert(betRecordByTime,betRecordByTimeDTO);
@ -424,7 +423,35 @@ public class GamesDGServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) { public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) {
return null; log.info("GamesDGServiceImpl [kickMember] 请求参数 {}", kickMemberRequestDTO);
Map<String, Object> key = this.getKey(kickMemberRequestDTO);
DGUserListResponseDTO userListResponseDTO = DGClient.memberOnlines(key);
if (!this.getIsSuccess(userListResponseDTO.getCodeId())) {
throw new ApiException(ErrorCode.KICK_OUT_AILED.getCode());
}
if (CollectionUtils.isEmpty(userListResponseDTO.getList())){
return Boolean.TRUE;
}
DGUserListResponseDTO.UserDTO userDTO = userListResponseDTO.getList().stream()
.filter(user -> user.getUsername().equals(kickMemberRequestDTO.getAccount()))
.findFirst()
.orElse(null);
if (Objects.isNull(userDTO)){
return Boolean.TRUE;
}
List<Long> memberIds = new ArrayList<>();
memberIds.add(userDTO.getMemberId());
Map<String, Object> params = new LinkedHashMap<>();
params.put("list",memberIds);
DGResponse dgResponse = DGClient.kickMember(params, key);
//判断是否获取成功
if (this.getIsSuccess(dgResponse.getCodeId())) {
return Boolean.TRUE;
} else {
throw new BaseException(dgResponse.getMsg());
}
} }
/** /**
@ -435,7 +462,29 @@ public class GamesDGServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) { public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode()); log.info("GamesDGServiceImpl [kickMemberAll] 请求参数 {}", kickMemberAllDTO);
Map<String, Object> key = this.getKey(kickMemberAllDTO);
DGUserListResponseDTO userListResponseDTO = DGClient.memberOnlines(key);
if (!this.getIsSuccess(userListResponseDTO.getCodeId())) {
throw new ApiException(ErrorCode.KICK_OUT_AILED.getCode());
}
if (CollectionUtils.isEmpty(userListResponseDTO.getList())){
return Boolean.TRUE;
}
List<Long> memberIds = userListResponseDTO.getList().stream().map(DGUserListResponseDTO.UserDTO::getMemberId).collect(Collectors.toList());
Map<String, Object> params = new LinkedHashMap<>();
params.put("list",memberIds);
DGResponse dgResponse = DGClient.kickMember(params, key);
//判断是否获取成功
if (this.getIsSuccess(dgResponse.getCodeId())) {
return Boolean.TRUE;
} else {
throw new BaseException(dgResponse.getMsg());
}
} }
/** /**
@ -470,7 +519,7 @@ public class GamesDGServiceImpl implements IGamesService {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>(); List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<String> wagersIds = new ArrayList<>(); List<String> wagersIds = new ArrayList<>();
//数据组装 //数据组装
List<DGBetRecordResponseDTO.ReportDTO> report = dgBetRecordResponseDTO.getReport(); List<DGBetRecordResponseDTO.ReportDTO> report = dgBetRecordResponseDTO.getList();
//数据转化 //数据转化
for (DGBetRecordResponseDTO.ReportDTO bean : report) { for (DGBetRecordResponseDTO.ReportDTO bean : report) {
GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).build()); GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).build());
@ -536,6 +585,7 @@ public class GamesDGServiceImpl implements IGamesService {
payoffAmount = NumberUtil.sub(resultBean.getWinOrLoss(), resultBean.getBetPoints()).negate(); payoffAmount = NumberUtil.sub(resultBean.getWinOrLoss(), resultBean.getBetPoints()).negate();
gameStatus = GameStatus.FAIL.getCode(); gameStatus = GameStatus.FAIL.getCode();
} }
Game game = gameService.selectGameById(GAME_ID);
//数据构造 //数据构造
@ -546,9 +596,9 @@ public class GamesDGServiceImpl implements IGamesService {
.memberId(member.getId()) .memberId(member.getId())
.gameCode(String.valueOf(resultBean.getGameId())) .gameCode(String.valueOf(resultBean.getGameId()))
.gameType(PlatformType.CARD_GAME.getCode()) .gameType(PlatformType.CARD_GAME.getCode())
.platformCode(GamePlatforms.SA.getCode()) .platformCode(GamePlatforms.DG.getInfo())
.gameId(GAME_ID) .gameId(GAME_ID)
.gameName(String.valueOf(resultBean.getGameId())) .gameName(game.getGameName())
.gameStatus(gameStatus) .gameStatus(gameStatus)
.gameStatusType(resultBean.getGameType()) .gameStatusType(resultBean.getGameType())
.gameCurrencyCode(currencyDTO.getCurrency()) .gameCurrencyCode(currencyDTO.getCurrency())
@ -556,6 +606,7 @@ public class GamesDGServiceImpl implements IGamesService {
.wagersId(String.valueOf(resultBean.getId())) .wagersId(String.valueOf(resultBean.getId()))
.wagersTime(resultBean.getBetTime().getTime()) .wagersTime(resultBean.getBetTime().getTime())
.betAmount(resultBean.getBetPoints()) .betAmount(resultBean.getBetPoints())
.betContent(resultBean.getBetDetail())
.payoffTime(resultBean.getCalTime().getTime()) .payoffTime(resultBean.getCalTime().getTime())
.payoffAmount(payoffAmount) .payoffAmount(payoffAmount)
.settlementTime(resultBean.getCalTime().getTime()) .settlementTime(resultBean.getCalTime().getTime())

View File

@ -32,7 +32,7 @@ public interface IMemberService
* *
* @return {@link String } * @return {@link String }
*/ */
String getMemberGameAccount(); String getMemberGameAccount(String platformCode);
/** /**
* *

View File

@ -3,6 +3,8 @@ package com.ff.member.service.impl;
import java.util.List; import java.util.List;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.ff.base.enums.GamePlatforms;
import com.ff.base.enums.PlatformType;
import com.ff.base.utils.DateUtils; import com.ff.base.utils.DateUtils;
import com.ff.base.utils.RandomGeneratorUtils; import com.ff.base.utils.RandomGeneratorUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -19,8 +21,7 @@ import org.springframework.util.ObjectUtils;
* @date 2025-02-10 * @date 2025-02-10
*/ */
@Service @Service
public class MemberServiceImpl implements IMemberService public class MemberServiceImpl implements IMemberService {
{
@Autowired @Autowired
private MemberMapper memberMapper; private MemberMapper memberMapper;
@ -31,8 +32,7 @@ public class MemberServiceImpl implements IMemberService
* @return * @return
*/ */
@Override @Override
public Member selectMemberById(Long id) public Member selectMemberById(Long id) {
{
return memberMapper.selectMemberById(id); return memberMapper.selectMemberById(id);
} }
@ -43,8 +43,7 @@ public class MemberServiceImpl implements IMemberService
* @return * @return
*/ */
@Override @Override
public List<Member> selectMemberList(Member member) public List<Member> selectMemberList(Member member) {
{
return memberMapper.selectMemberList(member); return memberMapper.selectMemberList(member);
} }
@ -54,12 +53,19 @@ public class MemberServiceImpl implements IMemberService
* @return {@link String } * @return {@link String }
*/ */
@Override @Override
public synchronized String getMemberGameAccount() { public synchronized String getMemberGameAccount(String platformCode) {
String gameAccount = null;
String gameAccount = RandomGeneratorUtils.generateRandomAccount(); if (GamePlatforms.DG.getInfo().equals(platformCode)) {
while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount))){ do {
gameAccount = RandomGeneratorUtils.generateRandomAccount(); gameAccount = RandomGeneratorUtils.generateRandomAccountUpper();
} while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount)));
} else {
do {
gameAccount = RandomGeneratorUtils.generateRandomAccount();
} while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount)));
} }
return gameAccount; return gameAccount;
} }
@ -70,8 +76,7 @@ public class MemberServiceImpl implements IMemberService
* @return * @return
*/ */
@Override @Override
public int insertMember(Member member) public int insertMember(Member member) {
{
member.setId(IdUtil.getSnowflakeNextId()); member.setId(IdUtil.getSnowflakeNextId());
member.setCreateTime(DateUtils.getNowDate()); member.setCreateTime(DateUtils.getNowDate());
return memberMapper.insertMember(member); return memberMapper.insertMember(member);
@ -84,8 +89,7 @@ public class MemberServiceImpl implements IMemberService
* @return * @return
*/ */
@Override @Override
public int updateMember(Member member) public int updateMember(Member member) {
{
member.setUpdateTime(DateUtils.getNowDate()); member.setUpdateTime(DateUtils.getNowDate());
return memberMapper.updateMember(member); return memberMapper.updateMember(member);
} }
@ -97,8 +101,7 @@ public class MemberServiceImpl implements IMemberService
* @return * @return
*/ */
@Override @Override
public int deleteMemberByIds(Long[] ids) public int deleteMemberByIds(Long[] ids) {
{
return memberMapper.deleteMemberByIds(ids); return memberMapper.deleteMemberByIds(ids);
} }
@ -109,13 +112,11 @@ public class MemberServiceImpl implements IMemberService
* @return * @return
*/ */
@Override @Override
public int deleteMemberById(Long id) public int deleteMemberById(Long id) {
{
return memberMapper.deleteMemberById(id); return memberMapper.deleteMemberById(id);
} }
/** /**
* *
* *
@ -137,6 +138,6 @@ public class MemberServiceImpl implements IMemberService
*/ */
@Override @Override
public Member selectMemberByAccount(String account, String currencyCode, String platformCode) { public Member selectMemberByAccount(String account, String currencyCode, String platformCode) {
return memberMapper.selectMemberByAccount(account,currencyCode,platformCode); return memberMapper.selectMemberByAccount(account, currencyCode, platformCode);
} }
} }