diff --git a/tkdata-model-server/src/main/java/cn/iocoder/yudao/module/tkdata/job/CleanTKAccountCache.java b/tkdata-model-server/src/main/java/cn/iocoder/yudao/module/tkdata/job/CleanTKAccountCache.java index 18bb0a4..9aadcb6 100644 --- a/tkdata-model-server/src/main/java/cn/iocoder/yudao/module/tkdata/job/CleanTKAccountCache.java +++ b/tkdata-model-server/src/main/java/cn/iocoder/yudao/module/tkdata/job/CleanTKAccountCache.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.tkdata.job; import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; -import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java index eeb1eb1..44b4c0b 100755 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java @@ -8,6 +8,7 @@ import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import javax.validation.constraints.NotNull; import java.time.LocalDateTime; @Schema(description = "管理后台 - 租户 Response VO") @@ -45,6 +46,14 @@ public class TenantRespVO { @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime expireTime; + + @Schema(description = "ai过期时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime aiExpireTime; + + @Schema(description = "大哥过期时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime brotherExpireTime; + + @Schema(description = "账号数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Integer accountCount; diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java index 0057d57..70972dc 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java @@ -45,6 +45,15 @@ public class TenantSaveReqVO { @NotNull(message = "过期时间不能为空") private LocalDateTime expireTime; + @Schema(description = "ai过期时间", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "过期时间不能为空") + private LocalDateTime aiExpireTime; + + @Schema(description = "大哥过期时间", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "过期时间不能为空") + private LocalDateTime brotherExpireTime; + + @Schema(description = "账号数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @NotNull(message = "账号数量不能为空") private Integer accountCount; diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java index 2797063..15085f1 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java @@ -74,6 +74,16 @@ public class TenantDO extends BaseDO { * 过期时间 */ private LocalDateTime expireTime; + + /** + * ai过期时间 + */ + private LocalDateTime aiExpireTime; + + /** + * 大哥过期时间 + */ + private LocalDateTime brotherExpireTime; /** * 账号数量 */ diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/job/DisableExpiredAccount.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/job/DisableExpiredAccount.java new file mode 100644 index 0000000..9a74168 --- /dev/null +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/job/DisableExpiredAccount.java @@ -0,0 +1,119 @@ +package cn.iocoder.yudao.module.system.job; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; +import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; +import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; +import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper; +import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; + +/** + * 禁用过期账号定时任务处理器 + *

+ * 该类用于定时检查并禁用已过期的AI账号和大哥账号。 + * 通过查询租户表中已过期的账号,然后将对应用户的权限状态更新为禁用。 + *

+ * + * @author ziin + * @date 2025/9/16 14:35 + */ +@Component +public class DisableExpiredAccount implements JobHandler{ + + /** + * 租户数据访问对象 + * 用于查询租户信息和过期时间 + */ + @Resource + TenantMapper tenantMapper; + + /** + * 管理员用户数据访问对象 + * 用于查询和更新用户权限状态 + */ + @Resource + private AdminUserMapper userMapper; + + /** + * 执行禁用过期账号的定时任务 + *

+ * 该方法会执行以下操作: + * 1. 查询所有AI账号已过期的租户 + * 2. 查询所有大哥账号已过期的租户 + * 3. 分别禁用这些租户下的用户对应权限 + * 4. 返回操作结果统计信息 + *

+ * + * @param param 任务参数(当前未使用) + * @return 操作结果字符串,包含禁用的AI账号和大哥账号数量 + * @throws Exception 执行过程中可能抛出的异常 + */ + @Override + @TenantJob + public String execute(String param) throws Exception { + // 获取今天的开始时间(00:00:00)和结束时间(23:59:59.999999999) + LocalDateTime todayStart = LocalDate.now().atStartOfDay(); + LocalDateTime todayEnd = LocalDate.now().atTime(LocalTime.MAX); + + Long tenantId = TenantContextHolder.getTenantId(); + + // 构建AI账号过期查询条件:查询AI过期时间在今天的租户 + LambdaQueryWrapper aiQueryWrapper = new LambdaQueryWrapper<>(); + aiQueryWrapper.between(TenantDO::getAiExpireTime, todayStart, todayEnd) + .eq(TenantDO::getId, tenantId) + .eq(TenantDO::getStatus, CommonStatusEnum.ENABLE.getStatus()); + + // 构建大哥账号过期查询条件:查询大哥过期时间在今天的租户 + LambdaQueryWrapper brotherQueryWrapper = new LambdaQueryWrapper<>(); + brotherQueryWrapper.between(TenantDO::getBrotherExpireTime, todayStart, todayEnd) + .eq(TenantDO::getId, tenantId) + .eq(TenantDO::getStatus, CommonStatusEnum.ENABLE.getStatus()); + + + // 初始化计数器:记录禁用的AI账号和大哥账号数量 + int aiAccountNum = 0 ; + int brotherAccountNum = 0 ; + + // 处理AI账号过期:查询所有AI账号已过期的租户,禁用其下所有用户的AI聊天权限 + TenantDO aiTenantDOS = tenantMapper.selectOne(aiQueryWrapper); + if (aiTenantDOS != null) { + LambdaQueryWrapper aiUserQueryWrapper = new LambdaQueryWrapper<>(); + aiUserQueryWrapper.eq(AdminUserDO::getTenantId, aiTenantDOS.getId()); + List aiUserList = userMapper.selectList(aiUserQueryWrapper); + // 禁用每个用户的AI聊天权限 + for (AdminUserDO adminUserDO : aiUserList) { + adminUserDO.setAiChat((byte) 0); + userMapper.updateById(adminUserDO); + aiAccountNum++; + } + } + // 处理大哥账号过期:查询所有大哥账号已过期的租户,禁用其下所有用户的大哥权限 + TenantDO brotherTenantDOS = tenantMapper.selectOne(brotherQueryWrapper); + if (brotherTenantDOS != null) { + LambdaQueryWrapper brotherUserQueryWrapper = new LambdaQueryWrapper<>(); + brotherUserQueryWrapper.eq(AdminUserDO::getTenantId, brotherTenantDOS.getId()); + List brotherUserList = userMapper.selectList(brotherUserQueryWrapper); + // 禁用每个用户的大哥权限 + for (AdminUserDO adminUserDO : brotherUserList) { + adminUserDO.setBigBrother((byte) 0); + userMapper.updateById(adminUserDO); + brotherAccountNum++; + } + } + + // 返回操作结果:包含禁用的AI账号和大哥账号数量统计 + return "禁用过期账号成功,禁用了 " + aiAccountNum + " 个 AI 账号,禁用了 " + brotherAccountNum + " 个 大哥账号。"; + } +} \ No newline at end of file