fix(service): 延后VIP体验次数扣减至AI响应成功后

This commit is contained in:
2026-01-27 21:11:45 +08:00
parent 22e5041447
commit f28e6b7c39

View File

@@ -376,41 +376,29 @@ public class ChatServiceImpl implements ChatService {
public ChatMessageVO message(String content, String userId, Long companionId) {
log.info("同步对话请求, userId: {}, companionId: {}, content: {}", userId, companionId, content);
// ============ VIP等级检查 ============
// ============ VIP等级检查(先检查,不增加次数) ============
AppConfig appConfig = cfgHolder.getRef().get();
KeyboardUser user = userService.getById(Long.parseLong(userId));
// 获取VIP等级null视为0
int vipLevel = user != null && user.getVipLevel() != null ? user.getVipLevel() : 0;
// 如果VIP等级 <= 1需要限制每日体验次数
if (vipLevel <= 1) {
Integer dailyLimit = appConfig.getUserRegisterProperties().getVipFreeTrialTalk();
String redisKey = CHAT_DAILY_LIMIT_PREFIX + userId;
// 记录是否需要扣减体验次数VIP等级 <= 1 的用户需要扣减)
boolean needDeductQuota = vipLevel <= 1;
String redisKey = CHAT_DAILY_LIMIT_PREFIX + userId;
Integer dailyLimit = appConfig.getUserRegisterProperties().getVipFreeTrialTalk();
// 如果VIP等级 <= 1先检查每日体验次数是否用完
if (needDeductQuota) {
// 获取当前使用次数
String countStr = stringRedisTemplate.opsForValue().get(redisKey);
int currentCount = countStr != null ? Integer.parseInt(countStr) : 0;
// 检查是否超出限制
// 检查是否超出限制,超出直接返回
if (currentCount >= dailyLimit) {
log.warn("用户 {} VIP等级 {} 已达到每日体验次数限制 {}", userId, vipLevel, dailyLimit);
throw new BusinessException(ErrorCode.VIP_TRIAL_LIMIT_REACHED);
}
// 增加使用次数
Long newCount = stringRedisTemplate.opsForValue().increment(redisKey);
// 设置到午夜过期(只有第一次设置时需要设置过期时间)
if (newCount != null && newCount == 1) {
// 计算到今天午夜的剩余秒数
LocalDateTime now = LocalDateTime.now(ZoneId.of("America/New_York"));
LocalDateTime midnight = LocalDateTime.of(LocalDate.now(ZoneId.of("America/New_York")).plusDays(1), LocalTime.MIDNIGHT);
long secondsUntilMidnight = ChronoUnit.SECONDS.between(now, midnight);
stringRedisTemplate.expire(redisKey, secondsUntilMidnight, TimeUnit.SECONDS);
}
log.info("用户 {} VIP等级 {} 今日已使用 {}/{} 次", userId, vipLevel, newCount, dailyLimit);
}
long startTime = System.currentTimeMillis();
@@ -431,6 +419,22 @@ public class ChatServiceImpl implements ChatService {
// 保存用户消息和AI响应到聊天记录
saveChatMessages(Long.parseLong(userId), companionId, content, response);
// ============ 成功后扣减体验次数 ============
if (needDeductQuota) {
Long newCount = stringRedisTemplate.opsForValue().increment(redisKey);
// 设置到午夜过期(只有第一次设置时需要设置过期时间)
if (newCount != null && newCount == 1) {
// 计算到今天午夜的剩余秒数
LocalDateTime now = LocalDateTime.now(ZoneId.of("America/New_York"));
LocalDateTime midnight = LocalDateTime.of(LocalDate.now(ZoneId.of("America/New_York")).plusDays(1), LocalTime.MIDNIGHT);
long secondsUntilMidnight = ChronoUnit.SECONDS.between(now, midnight);
stringRedisTemplate.expire(redisKey, secondsUntilMidnight, TimeUnit.SECONDS);
}
log.info("用户 {} VIP等级 {} 今日已使用 {}/{} 次", userId, vipLevel, newCount, dailyLimit);
}
// 生成音频任务 ID
String audioId = UUID.randomUUID().toString().replace("-", "");