yomi v4 integration

This commit is contained in:
tianfeng 2026-05-26 18:29:58 +08:00
parent 1931c70552
commit 71b2157b5b
8 changed files with 229 additions and 278 deletions

View File

@ -104,16 +104,12 @@ public class YomiGameRestController extends BaseController {
return YomiResponseWrapper.success(result); return YomiResponseWrapper.success(result);
} catch (ResponseException e) { } catch (ResponseException e) {
log.error("yomi changeBalance 业务异常: recordId={}, error={}", log.error("yomi changeBalance 业务异常: error={}", e.getMessage());
e.getMessage(), e.getMessage());
if (Objects.equals(e.getErrorCode(), WalletErrorCode.INSUFFICIENT_BALANCE.getCode())) { if (Objects.equals(e.getErrorCode(), WalletErrorCode.INSUFFICIENT_BALANCE.getCode())) {
return YomiResponseWrapper.fail( // v4协议余额不足返回10003
WalletErrorCode.INSUFFICIENT_BALANCE.getCode(), return YomiResponseWrapper.fail(10003, "gold not enough");
WalletErrorCode.INSUFFICIENT_BALANCE.getMessage()
);
} }
return YomiResponseWrapper.fail(500, e.getMessage()); return YomiResponseWrapper.fail(9998, e.getMessage());
} catch (Exception e) { } catch (Exception e) {
log.error("yomi changeBalance 系统异常: {}", e.getMessage(), e); log.error("yomi changeBalance 系统异常: {}", e.getMessage(), e);
return YomiResponseWrapper.fail(500, e.getMessage()); return YomiResponseWrapper.fail(500, e.getMessage());

View File

@ -47,8 +47,6 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -59,7 +57,10 @@ import java.util.concurrent.TimeUnit;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class YomiGameServiceImpl implements YomiGameService { public class YomiGameServiceImpl implements YomiGameService {
private static final String IDEMPOTENT_KEY_PREFIX = "yomi:change_balance:req:";
private static final long IDEMPOTENT_EXPIRE_SECONDS = 300L;
private final YomiConfig yomiConfig; private final YomiConfig yomiConfig;
private final RedisTemplate<String, String> redisTemplate; private final RedisTemplate<String, String> redisTemplate;
private final AuthClient authClient; private final AuthClient authClient;
@ -75,129 +76,152 @@ public class YomiGameServiceImpl implements YomiGameService {
private final ActivityRechargeTicketService activityRechargeTicketService; private final ActivityRechargeTicketService activityRechargeTicketService;
private final RoomDailyTaskProgressService roomDailyTaskProgressService; private final RoomDailyTaskProgressService roomDailyTaskProgressService;
private final RedisService redisService; private final RedisService redisService;
@Override @Override
public YomiTokenCO getToken(YomiGetTokenCmd cmd) { public YomiTokenCO getToken(YomiGetTokenCmd cmd) {
log.info("yomi获取token: userId={}, gameId={}", cmd.getUserId(), cmd.getGameId()); Long userId = Long.parseLong(cmd.getPlatUserId());
log.info("yomi获取token: platUserId={}, gameUid={}", userId, cmd.getGameUid());
try { try {
// 调用认证服务获取用户凭证 ResultResponse<UserCredential> credResp = authClient.getUserCredential(userId);
ResultResponse<UserCredential> response = authClient.getUserCredential(Long.parseLong(cmd.getUserId())); if (credResp == null || !credResp.checkSuccess() || credResp.getBody() == null) {
UserCredential credential = response.getBody();
if (credential == null) {
throw new RuntimeException("用户不存在"); throw new RuntimeException("用户不存在");
} }
UserProfile profile = userProfileGateway.getByUserId(userId);
// 生成系统标准token if (profile == null) {
String token = credential.token(); throw new RuntimeException("用户信息不存在");
}
// 过期时间(24小时后) ResultResponse<PennyAmount> balanceResp = walletGoldClient.getBalance(userId);
Long expireDate = System.currentTimeMillis() / 1000 + yomiConfig.getTokenExpireSeconds();
// 缓存token-userId映射
String cacheKey = buildTokenCacheKey(token);
redisTemplate.opsForValue().set(cacheKey, cmd.getUserId(),
yomiConfig.getTokenExpireSeconds(), TimeUnit.SECONDS);
return new YomiTokenCO(token, expireDate); String token = credResp.getBody().token();
long expireAt = System.currentTimeMillis() / 1000 + yomiConfig.getTokenExpireSeconds();
redisTemplate.opsForValue().set(buildTokenCacheKey(token), cmd.getPlatUserId(),
yomiConfig.getTokenExpireSeconds(), TimeUnit.SECONDS);
return YomiTokenCO.builder()
.platUserId(cmd.getPlatUserId())
.platUserOpenId("") // 项目暂无 openId 概念按协议传空
.nickname(profile.getUserNickname())
.avatar(profile.getUserAvatar())
.balance(balanceResp.getBody().getDollarAmount().longValue())
.platToken(token)
.expireAt(expireAt)
.build();
} catch (Exception e) { } catch (Exception e) {
log.error("yomi获取token失败: userId={}, error={}", cmd.getUserId(), e.getMessage(), e); log.error("yomi获取token失败: platUserId={}, error={}", userId, e.getMessage(), e);
throw new RuntimeException("获取token失败: " + e.getMessage()); throw new RuntimeException("获取token失败: " + e.getMessage());
} }
} }
@Override @Override
public YomiUserInfoCO getUserInfo(YomiUserInfoCmd cmd) { public YomiUserInfoCO getUserInfo(YomiUserInfoCmd cmd) {
String userId = cmd.getUserId(); Long userId = Long.parseLong(cmd.getPlatUserId());
log.info("yomi获取用户信息: userId={}, gameId={}", userId, cmd.getGameId());
try { try {
// 验证token if (!UserCredential.checkToken(cmd.getPlatToken(), userId)) {
if (!UserCredential.checkToken(cmd.getToken(), Long.parseLong(userId))) {
throw new Exception("token与用户ID不匹配"); throw new Exception("token与用户ID不匹配");
} }
UserProfile profile = userProfileGateway.getByUserId(userId);
// 获取用户信息
UserProfile profile = userProfileGateway.getByUserId(Long.parseLong(userId));
if (profile == null) { if (profile == null) {
throw new Exception("用户信息不存在"); throw new Exception("用户信息不存在");
} }
ResultResponse<PennyAmount> response = walletGoldClient.getBalance(userId);
// 获取用户余额 return YomiUserInfoCO.builder()
ResultResponse<PennyAmount> response = walletGoldClient.getBalance(Long.parseLong(userId)); .platUserId(cmd.getPlatUserId())
.platUserOpenId("") // 项目暂无 openId 概念按协议传空
YomiUserInfoCO result = new YomiUserInfoCO( .nickname(profile.getUserNickname())
userId, .avatar(profile.getUserAvatar())
profile.getUserNickname(), .balance(response.getBody().getDollarAmount().longValue())
profile.getUserAvatar(), .build();
response.getBody().getDollarAmount().intValue()
);
return result;
} catch (Exception e) { } catch (Exception e) {
log.error("yomi获取用户信息失败: userId={}, error={}", userId, e.getMessage(), e); log.error("yomi获取用户信息失败: platUserId={}, error={}", userId, e.getMessage(), e);
throw new RuntimeException(e.getMessage()); throw new RuntimeException(e.getMessage());
} }
} }
@Override @Override
public YomiBalanceCO changeBalance(YomiChangeBalanceCmd cmd) { public YomiBalanceCO changeBalance(YomiChangeBalanceCmd cmd) {
Long userId = Long.parseLong(cmd.getUserId()); Long userId = Long.parseLong(cmd.getPlatUserId());
Integer changeValue = cmd.getChangeValue(); String gameIdStr = String.valueOf(cmd.getGameUid());
log.info("yomi余额变动: userId={}, gameId={}, changeValue={}, changeCause={}, recordId={}", log.info("yomi余额变动: platUserId={}, gameUid={}, gold={}, reasonType={}, requestId={}",
userId, cmd.getGameId(), changeValue, cmd.getChangeCause(), cmd.getRecordId()); userId, cmd.getGameUid(), cmd.getGold(), cmd.getReasonType(), cmd.getRequestId());
try { try {
// 验证token if (!UserCredential.checkToken(cmd.getPlatToken(), userId)) {
String token = cmd.getToken();
String gameId = cmd.getGameId();
if (!UserCredential.checkToken(token, userId)) {
throw new Exception("token与用户ID不匹配"); throw new Exception("token与用户ID不匹配");
} }
WalletReceiptResDTO res = walletGoldClient.changeBalance(createReceipt(cmd)).getBody(); // 幂等检查requestId 已处理则直接返回当前余额
int currentBalance = res.getBalance().getDollarAmount().intValue(); String idempotentKey = IDEMPOTENT_KEY_PREFIX + cmd.getRequestId();
String processed = redisTemplate.opsForValue().get(idempotentKey);
// 获取游戏配置 if (processed != null) {
String sysOrigin = UserCredential.parseToken(token).getSysOrigin(); log.info("yomi余额变动重复请求直接返回: requestId={}", cmd.getRequestId());
GameListConfig gameConfig = gameListConfigService.getByGameId(gameId, GameOriginEnum.YOMI.name(), sysOrigin); long currentBalance = walletGoldClient.getBalance(userId).getBody().getDollarAmount().longValue();
if (gameConfig == null) {
log.error("游戏配置不存在, gameId={}", gameId);
return new YomiBalanceCO(currentBalance); return new YomiBalanceCO(currentBalance);
} }
// 发送广播通知 WalletReceiptResDTO res = walletGoldClient.changeBalance(createReceipt(cmd)).getBody();
if (!isConsume(cmd)) { long currentBalance = res.getBalance().getDollarAmount().longValue();
sendBroadcast(userId, changeValue, gameConfig.getCover());
// 累计游戏排行榜 // 执行成功后写入幂等标记
incGameRankingRecord(changeValue, gameConfig); redisTemplate.opsForValue().set(idempotentKey, "1", IDEMPOTENT_EXPIRE_SECONDS, TimeUnit.SECONDS);
// 游戏参与打榜活动 String sysOrigin = UserCredential.parseToken(cmd.getPlatToken()).getSysOrigin();
incGameRankingActivity(userId, changeValue, gameConfig.getGameId()); GameListConfig gameConfig = gameListConfigService.getByGameId(gameIdStr, GameOriginEnum.YOMI.name(), sysOrigin);
if (gameConfig == null) {
log.error("游戏配置不存在, gameUid={}", cmd.getGameUid());
return new YomiBalanceCO(currentBalance);
}
//处理游戏获得任务 if (!isBet(cmd)) {
gameActivityService.handleGameSpendTask(userId, changeValue.longValue()); sendBroadcast(userId, cmd.getGold().intValue(), gameConfig.getCover());
incGameRankingRecord(cmd.getGold().intValue(), gameConfig);
// 累加用户获得的金币并发送抽奖券 incGameRankingActivity(userId, cmd.getGold().intValue(), gameIdStr);
// activityRechargeTicketService.accumulatedRechargeAndAddTicket(userId, Math.abs(changeValue.longValue()), MonthlyRechargeType.UNDEFINED); gameActivityService.handleGameSpendTask(userId, cmd.getGold());
} else { } else {
updateRoomDailyTask(changeValue.longValue(), userId); updateRoomDailyTask(cmd.getGold(), userId);
} }
return new YomiBalanceCO(currentBalance); return new YomiBalanceCO(currentBalance);
} catch (Exception e) { } catch (Exception e) {
log.error("yomi余额变动失败: userId={}, recordId={}, error={}", log.error("yomi余额变动失败: platUserId={}, requestId={}, error={}",
userId, cmd.getRecordId(), e.getMessage(), e); userId, cmd.getRequestId(), e.getMessage(), e);
throw new RuntimeException("余额变动失败: " + e.getMessage()); throw new RuntimeException("余额变动失败: " + e.getMessage());
} }
} }
// ------------------------------------------------------------------ //
// 私有方法
// ------------------------------------------------------------------ //
private static boolean isBet(YomiChangeBalanceCmd cmd) {
return Integer.valueOf(1).equals(cmd.getReasonType());
}
private String buildTokenCacheKey(String token) {
return "yomi:token:" + token;
}
private GoldReceiptCmd createReceipt(YomiChangeBalanceCmd cmd) {
UserCredential userCredential = UserCredential.parseToken(cmd.getPlatToken());
String gameUidStr = String.valueOf(cmd.getGameUid());
return createGoldReceiptCmdBuilder(cmd.getReasonType())
.userId(Long.parseLong(cmd.getPlatUserId()))
.sysOrigin(userCredential.getSysOrigin())
.origin(GoldOrigin.YOMI_GAME.name() + "_" + gameUidStr)
.originDescribe(GoldOrigin.YOMI_GAME.getDesc() + "[" + gameUidStr + "]")
.eventId(String.valueOf(cmd.getGameRoundId()))
.amount(ArithmeticUtils.toBigDecimal(Math.abs(cmd.getGold())))
.build();
}
private GoldReceiptCmd.GoldReceiptCmdBuilder createGoldReceiptCmdBuilder(Integer reasonType) {
if (Integer.valueOf(1).equals(reasonType)) {
return GoldReceiptCmd.builder().appExpenditure();
}
if (Integer.valueOf(2).equals(reasonType)) {
return GoldReceiptCmd.builder().appIncome();
}
throw new IllegalArgumentException("yomi game param [reasonType] error: " + reasonType);
}
private void updateRoomDailyTask(Long coins, Long userId) { private void updateRoomDailyTask(Long coins, Long userId) {
RoomDailyTaskCode taskType = RoomDailyTaskCode.PERSONAL_GAME_CONSUME; RoomDailyTaskCode taskType = RoomDailyTaskCode.PERSONAL_GAME_CONSUME;
String redisKey = "room:daily:task:progress:" + taskType.name() + ":" + userId + ":" + ZonedDateTimeAsiaRiyadhUtils.now().toLocalDate(); String redisKey = "room:daily:task:progress:" + taskType.name() + ":" + userId + ":" + ZonedDateTimeAsiaRiyadhUtils.now().toLocalDate();
@ -211,92 +235,19 @@ public class YomiGameServiceImpl implements YomiGameService {
); );
} }
private static boolean isConsume(YomiChangeBalanceCmd cmd) {
return "bet".equals(cmd.getChangeCause());
}
/**
* 验证token有效性
*/
private String validateToken(String token) {
String cacheKey = buildTokenCacheKey(token);
String userId = redisTemplate.opsForValue().get(cacheKey);
if (userId == null) {
throw new RuntimeException("token已过期或无效");
}
return userId;
}
/**
* 构建token缓存key
*/
private String buildTokenCacheKey(String token) {
return "yomi:token:" + token;
}
private GoldReceiptCmd createReceipt(YomiChangeBalanceCmd cmd) {
UserCredential userCredential = UserCredential.parseToken(cmd.getToken());
return createGoldReceiptCmdBuilder(cmd.getChangeCause())
.userId(Long.parseLong(cmd.getUserId()))
.sysOrigin(userCredential.getSysOrigin())
.origin(GoldOrigin.YOMI_GAME.name() + "_" + cmd.getGameId())
.originDescribe(GoldOrigin.YOMI_GAME.getDesc() + "[" + cmd.getGameId() + "]")
.eventId(cmd.getRoundId())
.amount(ArithmeticUtils.toBigDecimal(Math.abs(cmd.getChangeValue())))
.build();
}
private GoldReceiptCmd.GoldReceiptCmdBuilder createGoldReceiptCmdBuilder(String changeCause) {
if ("bet".equals(changeCause)) {
return GoldReceiptCmd.builder().appExpenditure();
}
if ("awards".equals(changeCause)) {
return GoldReceiptCmd.builder().appIncome();
}
throw new IllegalArgumentException("yomi game param [changeCause] error: " + changeCause);
}
/**
* 构建游戏参数(用于广播和排行榜)
*/
private Map<String, Object> buildGameParam(YomiChangeBalanceCmd cmd, Long userId, GameListConfig gameConfig) {
Map<String, Object> param = new HashMap<>();
param.put("userId", userId);
param.put("gameId", cmd.getGameId());
param.put("roomId", cmd.getRoomId());
param.put("recordId", cmd.getRecordId());
param.put("roundId", cmd.getRoundId());
param.put("changeValue", cmd.getChangeValue());
param.put("changeCause", cmd.getChangeCause());
param.put("changeTime", cmd.getChangeTime());
param.put("gameConfig", gameConfig);
return param;
}
private void sendBroadcast(Long userId, Integer rewardAmount, String gameUrl) { private void sendBroadcast(Long userId, Integer rewardAmount, String gameUrl) {
if (rewardAmount == null || rewardAmount <= 0) { if (rewardAmount == null || rewardAmount <= 0) {
return; return;
} }
BigDecimal cost = enumConfigCacheService.getValueBigDecimal(EnumConfigKey.GAME_BROADCAST_AMOUNT, SysOriginPlatformEnum.ATYOU.name());
BigDecimal cost = enumConfigCacheService.getValueBigDecimal(EnumConfigKey.GAME_BROADCAST_AMOUNT, SysOriginPlatformEnum.ATYOU.name()) ;
int thresholdAmount = Optional.ofNullable(cost).orElse(new BigDecimal("5000")).intValue(); int thresholdAmount = Optional.ofNullable(cost).orElse(new BigDecimal("5000")).intValue();
if (rewardAmount < thresholdAmount) { if (rewardAmount < thresholdAmount) {
return; return;
} }
UserProfileDTO userProfile = userProfileAppConvertor.toUserProfileDTO(userProfileGateway.getByUserId(userId)); UserProfileDTO userProfile = userProfileAppConvertor.toUserProfileDTO(userProfileGateway.getByUserId(userId));
java.util.Map<Object, Object> build = OfficialNoticeUtils.buildUserProfile(userProfile);
Map<Object, Object> build = OfficialNoticeUtils.buildUserProfile(userProfile);
build.put("gameUrl", gameUrl); build.put("gameUrl", gameUrl);
build.put("currencyDiff", rewardAmount); build.put("currencyDiff", rewardAmount);
imGroupClient.sendMessageBroadcast( imGroupClient.sendMessageBroadcast(
BroadcastGroupMsgBodyCmd.builder() BroadcastGroupMsgBodyCmd.builder()
.toPlatform(SysOriginPlatformEnum.ATYOU) .toPlatform(SysOriginPlatformEnum.ATYOU)
@ -307,7 +258,6 @@ public class YomiGameServiceImpl implements YomiGameService {
} }
private void incGameRankingRecord(Integer rewardAmount, GameListConfig gameListConfig) { private void incGameRankingRecord(Integer rewardAmount, GameListConfig gameListConfig) {
GameRankingIncrementCmd build = GameRankingIncrementCmd.builder() GameRankingIncrementCmd build = GameRankingIncrementCmd.builder()
.gameOrigin(GameOriginEnum.YOMI.name()) .gameOrigin(GameOriginEnum.YOMI.name())
.gameId(gameListConfig.getGameId()) .gameId(gameListConfig.getGameId())
@ -321,7 +271,6 @@ public class YomiGameServiceImpl implements YomiGameService {
gameRankingGateway.incrementPrizeAmount(build); gameRankingGateway.incrementPrizeAmount(build);
} }
private void incGameRankingActivity(Long userId, Integer rewardAmount, String gameId) { private void incGameRankingActivity(Long userId, Integer rewardAmount, String gameId) {
RankingDataUpdateCmd receiverCmd = new RankingDataUpdateCmd(); RankingDataUpdateCmd receiverCmd = new RankingDataUpdateCmd();
receiverCmd.setUserId(userId); receiverCmd.setUserId(userId);
@ -334,8 +283,6 @@ public class YomiGameServiceImpl implements YomiGameService {
receiverCmd.setBizNo(gameId); receiverCmd.setBizNo(gameId);
receiverCmd.setReqSysOrigin(ReqSysOrigin.of(SysOriginPlatformEnum.ATYOU.name())); receiverCmd.setReqSysOrigin(ReqSysOrigin.of(SysOriginPlatformEnum.ATYOU.name()));
rankingActivityService.accumulateRankingData(receiverCmd); rankingActivityService.accumulateRankingData(receiverCmd);
//游戏王日榜
gameActivityService.incKingGameDaily(userId, rewardAmount.longValue(), gameId); gameActivityService.incKingGameDaily(userId, rewardAmount.longValue(), gameId);
} }
} }

View File

@ -1,21 +1,16 @@
package com.red.circle.other.app.dto.cmd.party3rd; package com.red.circle.other.app.dto.cmd.party3rd;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
/** /**
* Yomi余额响应 * Yomi余额响应 (v4)
*/ */
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class YomiBalanceCO { public class YomiBalanceCO {
/** private Long balance;
* 当前余额 }
*/
@JsonProperty("current_balance")
private Integer currentBalance;
}

View File

@ -1,39 +1,56 @@
package com.red.circle.other.app.dto.cmd.party3rd; package com.red.circle.other.app.dto.cmd.party3rd;
import jakarta.validation.constraints.NotBlank; import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* Yomi用户余额变动请求 * Yomi用户余额变动请求 (v4)
*/ */
@Data @Data
public class YomiChangeBalanceCmd { public class YomiChangeBalanceCmd {
@NotBlank(message = "游戏ID不能为空") /** 请求ID幂等标识 */
private String gameId; private Long requestId;
@NotBlank(message = "用户ID不能为空") private String platUserId;
private String userId;
private String platToken;
@NotBlank(message = "token不能为空")
private String token; /** 变动金额,取值范围[0~MaxBet]|[0~MaxReward] */
private Long gold;
@NotNull(message = "余额变化值不能为空")
private Integer changeValue; private Integer gameUid;
@NotBlank(message = "变化原因不能为空") /** 游戏场次 */
private String changeCause; private Integer gameLevelUid;
@NotNull(message = "变化时间不能为空") /** 1=投注 2=返奖 */
private Long changeTime; private Integer reasonType;
@NotBlank(message = "房间ID不能为空") /** 游戏轮局ID */
private String roomId; private Long gameRoundId;
@NotBlank(message = "记录ID不能为空") /** 游戏发生时间戳 */
private String recordId; private Integer timestamp;
@NotBlank(message = "轮次ID不能为空") private String platPayload;
private String roundId;
} private String platRoomId;
@JsonProperty("game_infos")
private List<GameInfo> gameInfos;
@Data
public static class GameInfo {
@JsonProperty("are_id")
private Integer areId;
@JsonProperty("are_name")
private String areName;
@JsonProperty("are_rate")
private Integer areRate;
private Long bet;
private Long award;
}
}

View File

@ -1,23 +1,28 @@
package com.red.circle.other.app.dto.cmd.party3rd; package com.red.circle.other.app.dto.cmd.party3rd;
import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
/** /**
* Yomi获取token请求 * Yomi获取token请求 (v4)
*/ */
@Data @Data
public class YomiGetTokenCmd { public class YomiGetTokenCmd {
@NotBlank(message = "游戏ID不能为空") /** Yomi分配的GameUID */
private String gameId; private Integer gameUid;
@NotBlank(message = "房间ID不能为空") /** 多语言 */
private String roomId; private String lang;
@NotBlank(message = "用户ID不能为空") /** 商户code */
private String userId; private String platAuthCode;
@NotBlank(message = "验证码不能为空") /** 用户ID */
private String code; private String platUserId;
/** 透传数据 */
private String platPayload;
/** 房间ID */
private String platRoomId;
} }

View File

@ -1,26 +1,30 @@
package com.red.circle.other.app.dto.cmd.party3rd; package com.red.circle.other.app.dto.cmd.party3rd;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
/** /**
* Yomi Token响应 * Yomi Token响应 (v4)
*/ */
@Data @Data
@Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class YomiTokenCO { public class YomiTokenCO {
/** private String platUserId;
* token
*/ private String platUserOpenId;
private String token;
private String nickname;
/**
* 过期时间(秒级时间戳) private String avatar;
*/
@JsonProperty("expire_date") private Long balance;
private Long expireDate;
} private String platToken;
private Long expireAt;
}

View File

@ -1,39 +1,26 @@
package com.red.circle.other.app.dto.cmd.party3rd; package com.red.circle.other.app.dto.cmd.party3rd;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
/** /**
* Yomi用户信息响应 * Yomi用户信息响应 (v4)
*/ */
@Data @Data
@Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class YomiUserInfoCO { public class YomiUserInfoCO {
/** private String platUserId;
* 用户ID
*/ private String platUserOpenId;
@JsonProperty("user_id")
private String userId; private String nickname;
/** private String avatar;
* 用户昵称
*/ private Long balance;
@JsonProperty("user_name") }
private String userName;
/**
* 用户头像
*/
@JsonProperty("user_avatar")
private String userAvatar;
/**
* 用户余额
*/
@JsonProperty("balance")
private Integer balance;
}

View File

@ -1,20 +1,20 @@
package com.red.circle.other.app.dto.cmd.party3rd; package com.red.circle.other.app.dto.cmd.party3rd;
import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
/** /**
* Yomi获取用户信息请求 * Yomi获取用户信息请求 (v4)
*/ */
@Data @Data
public class YomiUserInfoCmd { public class YomiUserInfoCmd {
@NotBlank(message = "游戏ID不能为空") private Integer gameUid;
private String gameId;
private String platUserId;
@NotBlank(message = "用户ID不能为空")
private String userId; private String platToken;
@NotBlank(message = "token不能为空") private String platPayload;
private String token;
private String platRoomId;
} }