Compare commits

...

9 Commits

Author SHA1 Message Date
shi 58cdc3a44b perf(api): 优化会员创建接口并发处理
- 在 ApiMemberController 的 createMember 方法上添加 synchronized 关键字
- 通过添加同步
2025-03-17 18:19:12 +08:00
shi 8a6a70b687 Merge branch 'main' into main-p 2025-03-17 18:17:59 +08:00
shi 0fcf4d0593 refactor(ff-game): 优化游戏结果状态处理逻辑
- 新增游戏状态判断逻辑,根据结算金额确定游戏结果
- 修改 gameStatus 字段赋值方式,提高代码可读性和维护性
2025-03-17 18:16:42 +08:00
shi c3f21c9b49 refactor(ff-game): 优化游戏结果状态处理逻辑
- 新增游戏状态判断逻辑,根据结算金额确定游戏结果
- 修改 gameStatus 字段赋值方式,提高代码可读性和维护性
2025-03-17 14:10:02 +08:00
shi 1affb42367 Merge remote-tracking branch 'origin/main-p' into main-p 2025-03-17 11:38:01 +08:00
shi 672c722a19 refactor(member): 重构会员游戏账号生成逻辑
- 在 ApiMemberController 中调用 memberService.getMemberGameAccount() 替代原有逻辑
- 在 IMemberService 中添加 getMemberGameAccount 方法接口
- 在 MemberServiceImpl 中实现 getMemberGameAccount 方法,生成唯一的游戏账号- 新增 RandomGeneratorUtils 工具类,用于生成随机账号字符串
2025-03-17 11:36:17 +08:00
shi 79d16e68db refactor(ff-game): 优化游戏结果状态处理逻辑
- 新增游戏状态判断逻辑,根据结算金额确定游戏结果
- 修改 gameStatus 字段赋值方式,提高代码可读性和维护性
2025-03-17 09:56:19 +08:00
shi 57214fe78c Merge branch 'main' into main-p 2025-03-15 15:17:53 +08:00
shi 080f7d1056 refactor(member): 重构会员游戏账号生成逻辑
- 在 ApiMemberController 中调用 memberService.getMemberGameAccount() 替代原有逻辑
- 在 IMemberService 中添加 getMemberGameAccount 方法接口
- 在 MemberServiceImpl 中实现 getMemberGameAccount 方法,生成唯一的游戏账号- 新增 RandomGeneratorUtils 工具类,用于生成随机账号字符串
2025-03-14 19:30:40 +08:00
8 changed files with 159 additions and 28 deletions

View File

@ -0,0 +1,32 @@
package com.ff.base.utils;
import java.security.SecureRandom;
import java.util.HashSet;
import java.util.Set;
/**
*
*
* @author shi
* @date 2025/03/14
*/
public class RandomGeneratorUtils {
private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyz0123456789";
private static final SecureRandom RANDOM = new SecureRandom();
/**
* 5-8
*
* @return {@link String }
*/
public static String generateRandomAccount() {
int length = 5 + RANDOM.nextInt(4);
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length())));
}
return sb.toString();
}
}

View File

@ -159,7 +159,7 @@ public class ApiGameController extends BaseController {
ApiException.notNull(gameSecretKeyLangDTO, ErrorCode.LANG_NOT_EXIST.getCode());
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
Member member = memberService.selectMemberByAccount(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode(), gamePlatform.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
GamesLogin gamesLogin = GamesLogin.builder()
@ -214,7 +214,8 @@ public class ApiGameController extends BaseController {
.build());
// 获取用户信息
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(gameExchangeBalanceRequest.getAccount(), gameExchangeBalanceRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
Member member = memberService.selectMemberByAccount(gameExchangeBalanceRequest.getAccount(), gameExchangeBalanceRequest.getCurrencyCode(), gameExchangeBalanceRequest.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
//操作第三方额度接口
@ -280,8 +281,11 @@ public class ApiGameController extends BaseController {
.systemCurrency(gameCreateFreeSpinRequest.getCurrencyCode()).build());
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(gameCreateFreeSpinRequest.getAccount(), gameCreateFreeSpinRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
Member member = memberService.selectMemberByAccount(gameCreateFreeSpinRequest.getAccount(), gameCreateFreeSpinRequest.getCurrencyCode(), gameCreateFreeSpinRequest.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
CreateFreeSpinRequestDTO createFreeSpinRequestDTO = CreateFreeSpinRequestDTO.builder()
.account(member.getGameAccount())
.currency(gameCreateFreeSpinRequest.getCurrencyCode())
@ -390,10 +394,12 @@ public class ApiGameController extends BaseController {
.systemCurrency(gameKickMemeberRequest.getCurrencyCode()).build());
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
TenantSecretKey tenantSecretKey = keyConfig.get();
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(gameKickMemeberRequest.getAccount(), gameKickMemeberRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
Member member = memberService.selectMemberByAccount(gameKickMemeberRequest.getAccount(), gameKickMemeberRequest.getCurrencyCode(), gameKickMemeberRequest.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
IGamesService iGamesService = gamesService.get(gameKickMemeberRequest.getPlatformCode() + Constants.SERVICE);
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
@ -498,8 +504,9 @@ public class ApiGameController extends BaseController {
public AjaxResult exchangeBalanceAll(@Validated @RequestBody GameExchangeBalanceAllRequest gameExchangeBalanceAllRequest) {
TenantSecretKey tenantSecretKey = keyConfig.get();
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(gameExchangeBalanceAllRequest.getAccount(), gameExchangeBalanceAllRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
List<GameSecretKeyCurrencyDTO> gameSecretKeys = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTOList(GameSecretKeyCurrencyDTO.builder()
@ -519,6 +526,10 @@ public class ApiGameController extends BaseController {
try {
IGamesService iGamesService = gamesService.get(gameSecretKeyCurrencyDTO.getPlatformCode() + Constants.SERVICE);
Member member = memberService.selectMemberByAccount(gameExchangeBalanceAllRequest.getAccount(), gameExchangeBalanceAllRequest.getCurrencyCode(), gameSecretKeyCurrencyDTO.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
//操作第三方钱包
ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO = ExchangeTransferMoneyRequestDTO.builder()
.agentId(gameSecretKeyCurrencyDTO.getCode())
@ -553,6 +564,7 @@ public class ApiGameController extends BaseController {
if (ObjectUtils.isEmpty(gameExchangeMoney)) {
continue;
}
Member member = memberService.selectMemberById(gameExchangeMoney.getMemberId());
balanceMap.put(gameExchangeMoney.getPlatformCode(), gameExchangeMoney.getBalance());
BigDecimal balance = gameExchangeMoney.getBalance();
balanceAll = NumberUtil.add(balanceAll, balance);

View File

@ -33,6 +33,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -91,7 +92,7 @@ public class ApiMemberController extends BaseController {
*/
@PostMapping("/create")
@Transactional
public AjaxResult createMember(@Validated @RequestBody MemberCreateApiRequest memberCreateApiRequest) {
public synchronized AjaxResult createMember(@Validated @RequestBody MemberCreateApiRequest memberCreateApiRequest) {
IGamesService iGamesService = gamesService.get(memberCreateApiRequest.getPlatformCode() + Constants.SERVICE);
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
@ -103,12 +104,18 @@ public class ApiMemberController extends BaseController {
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
String gameAccount = StringUtils.addSuffix(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn());
String gameAccount = StringUtils.addSuffix(memberService.getMemberGameAccount(), tenantSecretKey.getTenantSn());
// 获取用户信息
Member gameMember = memberService.selectMemberByAccount(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode(), memberCreateApiRequest.getPlatformCode());
if (!ObjectUtils.isEmpty(gameMember)){
throw new ApiException(ErrorCode.GAME_ACCOUNT_CREATION_FAILED.getCode());
}
List<Member> members = memberService.selectMemberList(Member.builder()
.tenantKey(tenantSecretKey.getTenantKey()).gameAccount(gameAccount).build());
if (CollectionUtils.isEmpty(members)) {
//注册本地账号
Member member = Member.builder()
.tenantKey(tenantSecretKey.getTenantKey())
@ -119,7 +126,7 @@ public class ApiMemberController extends BaseController {
.build();
int insertMember = memberService.insertMember(member);
Assert.isTrue(insertMember > 0, "建立游戏账号失败");
}
//向第三方注册账号
CreateMemberRequestDTO gamesBaseRequestDTO = CreateMemberRequestDTO.builder()
.account(gameAccount)
@ -153,9 +160,13 @@ public class ApiMemberController extends BaseController {
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(memberInfoApiRequest.getAccount(), memberInfoApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
// 获取用户信息
Member member = memberService.selectMemberByAccount(memberInfoApiRequest.getAccount(), memberInfoApiRequest.getCurrencyCode(), memberInfoApiRequest.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
//向第三方查询账号
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount())
@ -179,9 +190,8 @@ public class ApiMemberController extends BaseController {
@PostMapping("/info/all")
public AjaxResult infoAll(@Validated @RequestBody MemberInfoAllApiRequest memberInfoAllApiRequest) {
TenantSecretKey tenantSecretKey = keyConfig.get();
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(memberInfoAllApiRequest.getAccount(), memberInfoAllApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
List<GameSecretKeyCurrencyDTO> gameSecretKeys = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTOList(GameSecretKeyCurrencyDTO.builder()
@ -199,6 +209,12 @@ public class ApiMemberController extends BaseController {
futures.add(threadPoolTaskExecutor.submit(() -> {
try {
IGamesService iGamesService = gamesService.get(gameSecretKey.getPlatformCode() + Constants.SERVICE);
// 获取用户信息
Member member = memberService.selectMemberByAccount(memberInfoAllApiRequest.getAccount(), memberInfoAllApiRequest.getCurrencyCode(), gameSecretKey.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount())
.agentId(gameSecretKey.getCode())

View File

@ -313,8 +313,14 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
ApiException.notNull(tenantPlatform, ErrorCode.PLATFORM_NOT_EXIST.getCode());
// 获取用户信息
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(gameBalanceExchange.getAccount(), gameBalanceExchange.getCurrencyCode() + tenantSecretKey.getTenantSn()));
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());

View File

@ -2,6 +2,7 @@ package com.ff.member.mapper;
import java.util.List;
import com.ff.member.domain.Member;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
@ -69,4 +70,15 @@ public interface MemberMapper
* @return {@link Member }
*/
Member selectMemberByGameAccount(String gameAccount);
/**
*
*
* @param account
* @param currencyCode
* @param platformCode
* @return {@link Member }
*/
Member selectMemberByAccount(@Param("account") String account,@Param("currencyCode") String currencyCode,@Param("platformCode") String platformCode);
}

View File

@ -27,6 +27,13 @@ public interface IMemberService
*/
List<Member> selectMemberList(Member member);
/**
*
*
* @return {@link String }
*/
String getMemberGameAccount();
/**
*
*
@ -67,4 +74,14 @@ public interface IMemberService
* @return {@link Member }
*/
Member selectMemberByGameAccount(String gameAccount);
/**
*
*
* @param account
* @param currencyCode
* @param platformCode
* @return {@link Member }
*/
Member selectMemberByAccount(String account,String currencyCode,String platformCode);
}

View File

@ -4,11 +4,13 @@ import java.util.List;
import cn.hutool.core.util.IdUtil;
import com.ff.base.utils.DateUtils;
import com.ff.base.utils.RandomGeneratorUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ff.member.mapper.MemberMapper;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import org.springframework.util.ObjectUtils;
/**
* Service
@ -46,6 +48,21 @@ public class MemberServiceImpl implements IMemberService
return memberMapper.selectMemberList(member);
}
/**
*
*
* @return {@link String }
*/
@Override
public synchronized String getMemberGameAccount() {
String gameAccount = RandomGeneratorUtils.generateRandomAccount();
while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount))){
gameAccount = RandomGeneratorUtils.generateRandomAccount();
}
return gameAccount;
}
/**
*
*
@ -109,4 +126,17 @@ public class MemberServiceImpl implements IMemberService
public Member selectMemberByGameAccount(String gameAccount) {
return memberMapper.selectMemberByGameAccount(gameAccount.toLowerCase());
}
/**
*
*
* @param account
* @param currencyCode
* @param platformCode
* @return {@link Member }
*/
@Override
public Member selectMemberByAccount(String account, String currencyCode, String platformCode) {
return memberMapper.selectMemberByAccount(account,currencyCode,platformCode);
}
}

View File

@ -96,4 +96,10 @@
<include refid="selectMemberVo"/>
where game_account = #{gameAccount}
</select>
<select id="selectMemberByAccount" parameterType="String" resultMap="MemberResult">
<include refid="selectMemberVo"/>
where member_account = #{account} and platform_code = #{platformCode} and currency_code = #{currencyCode}
limit 1
</select>
</mapper>