From 81294313e09c422fc3f865ab53d2e8a2c3ffb6c8 Mon Sep 17 00:00:00 2001 From: WendyYang Date: Fri, 7 Jun 2024 10:35:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=93=E5=AE=B6=E6=8A=BD=E5=8F=96=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/meeting/task/ExpertRandomInviteTask.java | 107 ++++++++++++--------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/ExpertRandomInviteTask.java b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/ExpertRandomInviteTask.java index 36dac1d..a4cde9d 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/ExpertRandomInviteTask.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/ExpertRandomInviteTask.java @@ -1,8 +1,7 @@ package com.hz.pm.api.meeting.task; import cn.hutool.core.util.ArrayUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.hz.pm.api.common.util.SpringContextHolder; import com.hz.pm.api.meeting.builder.ExpertInviteBuilder; @@ -37,7 +36,11 @@ import org.springframework.util.Assert; import javax.annotation.PostConstruct; import javax.annotation.Resource; -import java.time.*; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.ChronoUnit; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -72,19 +75,43 @@ public class ExpertRandomInviteTask { private final IExpertInviteRuleService inviteRuleService; private final IMeetingService meetingService; private final ExpertInviteManage expertInviteManage; - private final IExpertInviteAvoidRuleService inviteAvoidRuleService; + private final IExpertInviteAvoidRuleService avoidRuleService; private final MeetingNotifyHelper meetingNotifyHelper; private final MeetingSettingsManage meetingSettingsManage; + /** * 用来存入线程执行句柄, 停止定时任务时使用 */ private static final ConcurrentMap> INVITE_TASK_MAP = new ConcurrentHashMap<>(); - private CacheHashKey getCacheKey(Long meetingId) { + //================================================================================================================== + + @PostConstruct + public void initTask() { + if (Boolean.FALSE.equals(properties.getEnable())) { + log.warn("随机邀请已关闭"); + return; + } + initInviteTaskAfterStarted(); + } + + /** + * 构建会议缓存key + * + * @param meetingId 会议ID + * @return 缓存key + */ + @SuppressWarnings("all") + private static CacheHashKey cacheKey(Long meetingId) { String field = meetingId == null ? null : meetingId.toString(); return new CacheHashKey(MEETING_ID_INVITE_RANDOM, field, EXPIRE_TIME); } + /** + * 校验是否在专家抽取任务执行时间之内 + * + * @return \ + */ private boolean inInviteTimeRange() { MeetingSettingsSaveReq settings = meetingSettingsManage.getSettings(MeetingSettingsTypeEnum.INVITE_CALL_IGNORE_TIME); LocalTime currTime = LocalTime.now(); @@ -97,20 +124,11 @@ public class ExpertRandomInviteTask { } } - @PostConstruct - public void initTask() { - if (Boolean.FALSE.equals(properties.getEnable())) { - log.warn("随机邀请已关闭……"); - return; - } - initInviteTaskAfterStarted(); - } - /** * 项目重启之后重新初始化邀请任务 */ private void initInviteTaskAfterStarted() { - Map caches = cachePlusOps.hGetAll(getCacheKey(null)); + Map caches = cachePlusOps.hGetAll(cacheKey(null)); if (MapUtils.isEmpty(caches)) { log.info("暂无需要初始化的抽取会议信息"); return; @@ -121,7 +139,7 @@ public class ExpertRandomInviteTask { LocalDateTime tsTime = cache.getTaskStartTime(); boolean added = addInviteTask(cache.getMeetingId(), true, inviteDelay, reInvite, tsTime); if (!added) { - cachePlusOps.hDel(getCacheKey(cache.getMeetingId())); + cachePlusOps.hDel(cacheKey(cache.getMeetingId())); } } } @@ -138,7 +156,7 @@ public class ExpertRandomInviteTask { if (ruleMap.isEmpty()) { return Boolean.FALSE; } - LambdaQueryWrapper query = Wrappers.lambdaQuery(MeetingExpert.class) + Wrapper query = Wrappers.lambdaQuery(MeetingExpert.class) .select(MeetingExpert::getRuleId, MeetingExpert::getStatus) .in(MeetingExpert::getRuleId, ruleMap.keySet()) .eq(MeetingExpert::getStatus, ExpertAttendStatusEnum.AGREED.getCode()); @@ -165,41 +183,44 @@ public class ExpertRandomInviteTask { **/ public void notifyInviteTask(Long meetingId, boolean... reInvite) { boolean tmpReInvite = ArrayUtil.isEmpty(reInvite) || reInvite[0]; - if (!INVITE_TASK_MAP.containsKey(meetingId)) { - if (addInviteTask(meetingId, false, properties.getInviteDelay(), tmpReInvite, LocalDateTime.now())) { - log.info("重置会议的随机抽取状态:{}", meetingId); - LambdaUpdateWrapper update = Wrappers.lambdaUpdate(Meeting.class); - update.set(Meeting::getInviteStatus, false); - update.eq(Meeting::getId, meetingId); - meetingService.update(update); - InviteCacheDTO cacheVal = InviteCacheDTO.of(meetingId, tmpReInvite, LocalDateTime.now()); - cachePlusOps.hSet(getCacheKey(meetingId), cacheVal); - } + if (INVITE_TASK_MAP.containsKey(meetingId)) { + return; + } + LocalDateTime now = LocalDateTime.now(); + if (addInviteTask(meetingId, false, properties.getInviteDelay(), tmpReInvite, now)) { + log.info("重置会议的随机抽取状态:{}", meetingId); + Wrapper update = Wrappers.lambdaUpdate(Meeting.class) + .set(Meeting::getInviteStatus, false) + .eq(Meeting::getId, meetingId); + meetingService.update(update); + InviteCacheDTO cacheVal = InviteCacheDTO.of(meetingId, tmpReInvite, now); + cachePlusOps.hSet(cacheKey(meetingId), cacheVal); } } /** * 添加专家抽取校验任务 * - * @param meetingId 会议ID - * @param checked 是否前置校验 - * @param delayTime 延迟执行时间 - * @param reInvite 是否可以邀请被拒绝的专家 - * @param tsTime 任务启动时间 + * @param meetingId 会议ID + * @param checked 是否前置校验 + * @param delayTime 延迟执行时间 + * @param reInvite 是否可以邀请被拒绝的专家 + * @param taskStataTime 任务启动时间 * @return 是否添加任务成功 * @author WendyYang **/ - private boolean addInviteTask(Long meetingId, boolean checked, int delayTime, boolean reInvite, LocalDateTime tsTime) { + private boolean addInviteTask(Long meetingId, boolean checked, int delayTime, + boolean reInvite, LocalDateTime taskStataTime) { if (checked && !inviteCountCheck(meetingId)) { // 如果抽取数量满足直接返回 return Boolean.FALSE; } - Instant startTime = LocalDateTime.now().plusMinutes(delayTime).atZone(ZoneId.systemDefault()).toInstant(); + Instant startTime = Instant.now().plus(delayTime, ChronoUnit.MINUTES); ScheduledFuture future = scheduler.scheduleAtFixedRate(() -> { ExpertRandomInviteTask bean = SpringContextHolder.getBean(ExpertRandomInviteTask.class); try { // 抽取专家 - bean.invite(meetingId, reInvite, tsTime); + bean.invite(meetingId, reInvite, taskStataTime); } catch (Exception e) { log.error("执行专家邀请任务异常:{}", meetingId, e); } @@ -212,15 +233,15 @@ public class ExpertRandomInviteTask { /** * 创建会议时添加抽取任务 * - * @param meetingId 会议ID - * @param tsTime 开始时间 + * @param meetingId 会议ID + * @param taskStartTime 开始时间 * @author WendyYang **/ - public void addInviteTaskByMeetingCreate(Long meetingId, LocalDateTime tsTime) { + public void addInviteTaskByMeetingCreate(Long meetingId, LocalDateTime taskStartTime) { Assert.isTrue(properties.getEnable(), "随机邀请已关闭"); - addInviteTask(meetingId, false, properties.getInviteDelay(), false, tsTime); - InviteCacheDTO cacheVal = InviteCacheDTO.of(meetingId, false, tsTime); - cachePlusOps.hSet(getCacheKey(meetingId), cacheVal); + addInviteTask(meetingId, false, properties.getInviteDelay(), false, taskStartTime); + InviteCacheDTO cacheVal = InviteCacheDTO.of(meetingId, false, taskStartTime); + cachePlusOps.hSet(cacheKey(meetingId), cacheVal); } /** @@ -247,7 +268,7 @@ public class ExpertRandomInviteTask { // 随机邀请规则 Map ruleMap = inviteRuleService.randomRuleByMeetingId(meetingId); // 回避规则 - AvoidRuleDTO avoidRule = inviteAvoidRuleService.getAvoidInfo(meetingId); + AvoidRuleDTO avoidRule = avoidRuleService.getAvoidInfo(meetingId); // 还需要抽取的规则数量 AtomicInteger notIgnoreCnt = new AtomicInteger(ruleMap.size()); AtomicInteger notSupportCnt = new AtomicInteger(0); @@ -304,7 +325,7 @@ public class ExpertRandomInviteTask { } private void killTaskAndDelCacheMeetingId(Long meetingId) { - cachePlusOps.hDel(getCacheKey(meetingId)); + cachePlusOps.hDel(cacheKey(meetingId)); ScheduledFuture future = INVITE_TASK_MAP.get(meetingId); if (future != null) { INVITE_TASK_MAP.remove(meetingId);