Compare commits

..

6 Commits

Author SHA1 Message Date
ba86ac45f4 feat(core): 新增VIP到期定时检查任务 2026-04-09 14:22:14 +08:00
d1f1e72732 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	keyboard-server/src/main/java/com/yolo/keyboard/dal/dataobject/aicompanion/AiCompanionI18nDO.java
2026-04-08 17:51:01 +08:00
ab09d0ee74 refactor(aicompanion): 将开场白字段迁移至 i18n 表
- 从 KeyboardAiCompanionDO 移除 prologue 与 prologueAudio
- 在 AiCompanionI18nDO 新增对应字段
- 同步调整 Mapper 查询逻辑
2026-04-08 17:50:47 +08:00
407438fb99 refactor(aicompanion): 将开场白字段迁移至 i18n 表
- 从 KeyboardAiCompanionDO 移除 prologue 与 prologueAudio
- 在 AiCompanionI18nDO 新增对应字段
- 同步调整 Mapper 查询逻辑
2026-04-08 17:49:37 +08:00
d0f4ad25c0 refactor(vo): 移除创建与更新时间的必填校验 2026-04-08 09:52:10 +08:00
da7bfbc9ce refactor(vo): 移除创建与更新时间的必填校验 2026-04-07 14:47:48 +08:00
9 changed files with 78 additions and 12 deletions

View File

@@ -51,11 +51,9 @@ public class KeyboardAiCompanionSaveReqVO {
private Integer popularityScore;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "创建时间不能为空")
private LocalDateTime createdAt;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "更新时间不能为空")
private LocalDateTime updatedAt;
@Schema(description = "开场白")

View File

@@ -52,4 +52,7 @@ public class KeyboardProductItemsPageReqVO extends PageParam {
@Schema(description = "订阅等级")
private Integer level;
@Schema(description = "平台")
private String platform;
}

View File

@@ -67,4 +67,7 @@ public class KeyboardProductItemsRespVO {
@Schema(description = "订阅等级")
private Integer level;
@Schema(description = "平台")
private String platform;
}

View File

@@ -59,4 +59,7 @@ public class KeyboardProductItemsSaveReqVO {
@Schema(description = "订阅等级")
private Integer level;
@Schema(description = "平台")
private String platform;
}

View File

@@ -57,4 +57,7 @@ public class AiCompanionI18nDO {
*/
private LocalDateTime updatedAt;
private String prologue;
private String prologueAudio;
}

View File

@@ -83,14 +83,6 @@ public class KeyboardAiCompanionDO {
* 更新时间
*/
private LocalDateTime updatedAt;
/**
* 开场白
*/
private String prologue;
/**
* 开场白音频
*/
private String prologueAudio;
/**
* 音频Id
*/

View File

@@ -1,6 +1,7 @@
package com.yolo.keyboard.dal.dataobject.productitems;
import com.yolo.keyboard.framework.tenant.core.aop.TenantIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
@@ -81,4 +82,6 @@ public class KeyboardProductItemsDO{
* 订阅等级
*/
private Integer level;
private String platform;
}

View File

@@ -32,8 +32,6 @@ public interface KeyboardAiCompanionMapper extends BaseMapperX<KeyboardAiCompani
.eqIfPresent(KeyboardAiCompanionDO::getPopularityScore, reqVO.getPopularityScore())
.eqIfPresent(KeyboardAiCompanionDO::getCreatedAt, reqVO.getCreatedAt())
.eqIfPresent(KeyboardAiCompanionDO::getUpdatedAt, reqVO.getUpdatedAt())
.eqIfPresent(KeyboardAiCompanionDO::getPrologue, reqVO.getPrologue())
.eqIfPresent(KeyboardAiCompanionDO::getPrologueAudio, reqVO.getPrologueAudio())
.eqIfPresent(KeyboardAiCompanionDO::getVoiceId, reqVO.getVoiceId())
.orderByDesc(KeyboardAiCompanionDO::getId));
}

View File

@@ -0,0 +1,63 @@
package com.yolo.keyboard.job;
import cn.hutool.core.collection.CollUtil;
import com.yolo.keyboard.dal.dataobject.user.KeyboardUserDO;
import com.yolo.keyboard.dal.mysql.user.KeyboardUserMapper;
import com.yolo.keyboard.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yolo.keyboard.framework.quartz.core.handler.JobHandler;
import com.yolo.keyboard.framework.tenant.core.aop.TenantIgnore;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.List;
/**
* VIP 到期检查定时任务
* 定期执行,将 VIP 已过期的用户关闭 VIP 权限
*
* @author ziin
*/
@Component
@Slf4j
public class VipExpiryCheckJob implements JobHandler {
@Resource
private KeyboardUserMapper userMapper;
@Override
@TenantIgnore
public String execute(String param) {
log.info("[VipExpiryCheckJob] 开始执行 VIP 到期检查任务");
LocalDateTime now = LocalDateTime.now();
// 查询 VIP 已过期且仍处于 VIP 状态的用户
List<KeyboardUserDO> expiredUsers = userMapper.selectList(
new LambdaQueryWrapperX<KeyboardUserDO>()
.eq(KeyboardUserDO::getIsVip, true)
.le(KeyboardUserDO::getVipExpiry, now)
);
if (CollUtil.isEmpty(expiredUsers)) {
log.info("[VipExpiryCheckJob] 没有需要处理的过期 VIP 用户");
return "没有需要处理的过期 VIP 用户";
}
int count = 0;
for (KeyboardUserDO user : expiredUsers) {
user.setIsVip(false);
user.setUpdatedAt(now);
userMapper.updateById(user);
count++;
log.info("[VipExpiryCheckJob] 用户 {} VIP 已过期,已关闭 VIP 权限,过期时间: {}",
user.getUid(), user.getVipExpiry());
}
String result = String.format("共处理 %d 个过期 VIP 用户", count);
log.info("[VipExpiryCheckJob] 任务执行完成: {}", result);
return result;
}
}