diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/MeetingController.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/MeetingController.java index 5ea0587..f554dc3 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/MeetingController.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/MeetingController.java @@ -39,6 +39,13 @@ public class MeetingController { return meetingManage.meetingCreateAndInviteExpert(req); } + @PostMapping("/continueInvite") + @ApiOperation(value = "续抽专家") + @WebLog(value = "续抽专家") + public void continueInvite(@Valid @RequestBody MeetingIdReq req) { + meetingManage.continueInvite(req.getMeetingId()); + } + @PostMapping("/expertInviteByCreate") @ApiOperation(value = "新建会议-专家抽取", hidden = true) @WebLog(value = "新建会议-专家抽取") @@ -94,13 +101,6 @@ public class MeetingController { return meetingManage.inviteRuleDetail(meetingId); } - @ApiOperation("专家替换") - @PostMapping("/expertReplace") - @WebLog(value = "专家替换") - public void expertReplace(@RequestBody ExpertRemoveReq po) { - meetingManage.expertReplace(po); - } - @ApiOperation("停止抽取") @GetMapping("/stopInvite/{meetingId}") @WebLog(value = "停止抽取") diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/domain/MeetingExpert.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/domain/MeetingExpert.java index e8cf1aa..be63408 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/domain/MeetingExpert.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/domain/MeetingExpert.java @@ -55,11 +55,6 @@ public class MeetingExpert implements Serializable { @ApiModelProperty("是否是专家组长") private Boolean isHeadman; - @ApiModelProperty("前一个状态") - private Integer preStatus; - - private Long preId; - @ApiModelProperty("邀请类型") private Integer inviteType; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/AvoidInfoDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/AvoidRuleDTO.java similarity index 93% rename from pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/AvoidInfoDTO.java rename to pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/AvoidRuleDTO.java index d32b7a0..ada8371 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/AvoidInfoDTO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/AvoidRuleDTO.java @@ -5,7 +5,6 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; import java.util.List; /** @@ -18,7 +17,7 @@ import java.util.List; */ @Data @ApiModel("回避信息") -public class AvoidInfoDTO { +public class AvoidRuleDTO { @ApiModelProperty("回避单位") @NotEmpty(message = "回避单位不能为空", groups = {AbstractInviteRule.RuleSave.class}) diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/MeetingInviteCacheDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/MeetingInviteCacheDTO.java new file mode 100644 index 0000000..9c3fea6 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/MeetingInviteCacheDTO.java @@ -0,0 +1,27 @@ +package com.ningdatech.pmapi.meeting.entity.dto; + +import lombok.Data; + +/** + *

+ * MeetingInviteDTO + *

+ * + * @author WendyYang + * @since 19:21 2023/3/7 + */ +@Data +public final class MeetingInviteCacheDTO { + + private Long meetingId; + + private Boolean invitedRefused; + + public static MeetingInviteCacheDTO of(Long meetingId, Boolean invitedRefused) { + MeetingInviteCacheDTO bo = new MeetingInviteCacheDTO(); + bo.setMeetingId(meetingId); + bo.setInvitedRefused(invitedRefused); + return bo; + } + +} \ No newline at end of file diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/ExpertInviteReq.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/ExpertInviteReq.java index 400da36..b28599d 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/ExpertInviteReq.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/ExpertInviteReq.java @@ -1,7 +1,7 @@ package com.ningdatech.pmapi.meeting.entity.req; import com.ningdatech.pmapi.meeting.entity.dto.AppointInviteRuleDTO; -import com.ningdatech.pmapi.meeting.entity.dto.AvoidInfoDTO; +import com.ningdatech.pmapi.meeting.entity.dto.AvoidRuleDTO; import com.ningdatech.pmapi.meeting.entity.dto.RandomInviteRuleDTO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -33,7 +33,7 @@ public class ExpertInviteReq { @Valid @NotNull(message = "回避信息不能为空") @ApiModelProperty("回避信息") - private AvoidInfoDTO avoidRule; + private AvoidRuleDTO avoidRule; @Valid @ApiModelProperty("随机抽取规则") diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/MeetingIdReq.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/MeetingIdReq.java new file mode 100644 index 0000000..f783032 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/MeetingIdReq.java @@ -0,0 +1,20 @@ +package com.ningdatech.pmapi.meeting.entity.req; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + *

+ * MeetingIdReq + *

+ * + * @author WendyYang + * @since 17:10 2023/3/7 + */ +@Data +public class MeetingIdReq { + + @ApiModelProperty("会议ID") + private Long meetingId; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/helper/ExpertInviteHelper.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/helper/ExpertInviteHelper.java index ad6dc68..1c4e02f 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/helper/ExpertInviteHelper.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/helper/ExpertInviteHelper.java @@ -11,7 +11,7 @@ import com.ningdatech.pmapi.meeting.entity.domain.Meeting; import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpert; import com.ningdatech.pmapi.meeting.entity.dto.AbstractInviteRule; import com.ningdatech.pmapi.meeting.entity.dto.AppointInviteRuleDTO; -import com.ningdatech.pmapi.meeting.entity.dto.AvoidInfoDTO; +import com.ningdatech.pmapi.meeting.entity.dto.AvoidRuleDTO; import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; import com.ningdatech.pmapi.meeting.service.IMeetingExpertService; import com.ningdatech.pmapi.meeting.service.IMeetingService; @@ -69,7 +69,7 @@ public class ExpertInviteHelper { return new HashSet<>(listInvitedExpertByTime(start, end)); } - public Set getAvoidExpert(List appoints, AvoidInfoDTO avoid, LocalDateTime start, LocalDateTime end) { + public Set getAvoidExpert(List appoints, AvoidRuleDTO avoid, LocalDateTime start, LocalDateTime end) { Set expertIds = new HashSet<>(); Optional.ofNullable(appoints).ifPresent(expertIds::addAll); Optional.ofNullable(avoid) diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/helper/MeetingManageHelper.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/helper/MeetingManageHelper.java index faf2e92..a699740 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/helper/MeetingManageHelper.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/helper/MeetingManageHelper.java @@ -1,5 +1,6 @@ package com.ningdatech.pmapi.meeting.helper; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -14,9 +15,10 @@ import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService; import com.ningdatech.pmapi.meeting.entity.domain.ExpertInviteAvoidRule; import com.ningdatech.pmapi.meeting.entity.domain.Meeting; import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpert; -import com.ningdatech.pmapi.meeting.entity.dto.AvoidInfoDTO; +import com.ningdatech.pmapi.meeting.entity.dto.AvoidRuleDTO; import com.ningdatech.pmapi.meeting.entity.dto.MeetingAndAttendStatusDTO; import com.ningdatech.pmapi.meeting.entity.dto.MeetingBasicDTO; +import com.ningdatech.pmapi.meeting.entity.dto.RandomInviteRuleDTO; import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; import com.ningdatech.pmapi.meeting.entity.req.MeetingListReq; import com.ningdatech.pmapi.meeting.entity.vo.ExpertBasicInfoVO; @@ -30,7 +32,10 @@ import lombok.AllArgsConstructor; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Component; -import java.util.*; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Map; /** *

@@ -60,6 +65,36 @@ public class MeetingManageHelper { } /** + * 校验会议是否还可继续抽取 + */ + public boolean checkCouldBeInvitedContinue(Long meetingId) { + Map ruleMap = inviteRuleService.randomRuleByMeetingId(meetingId); + List experts = meetingExpertService.listExpertLastByMeetingId(meetingId); + if (experts.isEmpty()) { + return Boolean.TRUE; + } + Map> expertMap = CollUtils.group(experts, MeetingExpert::getRuleId); + for (Map.Entry entry : ruleMap.entrySet()) { + List tmpExperts = expertMap.get(entry.getKey()); + if (CollUtil.isEmpty(tmpExperts)) { + return Boolean.TRUE; + } + int count = 0; + for (MeetingExpert w : tmpExperts) { + boolean status = ExpertAttendStatusEnum.AGREED.eq(w.getStatus()) || + ExpertAttendStatusEnum.NOTICING.eq(w.getStatus()); + if (status) { + count++; + } + } + if (count < entry.getValue().getCount()) { + return Boolean.TRUE; + } + } + return Boolean.FALSE; + } + + /** * 获取专家出席会议的状态 * * @param info 会议状态及评价信息 @@ -104,7 +139,7 @@ public class MeetingManageHelper { query.and(q1 -> q1.exists("select 1 from nd_project np inner join meeting_inner_project mip on mip.project_id = np.id" + " where mip.meeting_id = meeting.id and np.project_name like {0}", projectName) .or(q2 -> q2.exists("select 1 from meeting_outer_project mop where mop.meeting_id = meeting.id" + - "and mop.project_name like {0}", projectName))); + " and mop.project_name like {0}", projectName))); } } @@ -140,9 +175,9 @@ public class MeetingManageHelper { return null; } - public AvoidInfoDTO getAvoidInfoDto(Long meetingId) { + public AvoidRuleDTO getAvoidInfoDto(Long meetingId) { ExpertInviteAvoidRule avoidRule = inviteAvoidRuleService.getByMeetingId(meetingId); - AvoidInfoDTO result = new AvoidInfoDTO(); + AvoidRuleDTO result = new AvoidRuleDTO(); result.setAvoidOrgIdList(StrUtil.split(avoidRule.getAvoidOrgIds(), ",")); result.setExpertIds(BizUtils.splitToLong(avoidRule.getAvoidExpertIds())); result.setAvoidUnitIdList(StrUtil.split(avoidRule.getAvoidUnitIds(), ",")); @@ -165,7 +200,7 @@ public class MeetingManageHelper { **/ public List appointExpertCheck(Long meetingId, List expertIds) { List experts = expertUserFullInfoService.listByUserId(expertIds); - AvoidInfoDTO avoidRule = getAvoidInfoDto(meetingId); + AvoidRuleDTO avoidRule = getAvoidInfoDto(meetingId); experts.forEach(expert -> { if (avoidRule.getAvoidUnitIdList().contains(expert.getCompany())) { throw BizException.wrap("请移除已回避单位的专家"); @@ -193,16 +228,6 @@ public class MeetingManageHelper { throw BizException.wrap("专家%s已拒绝参加", expertName); case REMOVED: throw BizException.wrap("专家%s已被移除", expertName); - case REPLACED: - switch (ExpertAttendStatusEnum.getByCode(w.getPreStatus())) { - case REFUSED: - throw BizException.wrap("专家%s已拒绝参加", expertName); - case REMOVED: - throw BizException.wrap("专家%s已被移除", expertName); - default: - break; - } - break; case AGREED: throw BizException.wrap("专家%s已同意参加", expertName); case NOTICING: diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/ExpertInviteManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/ExpertInviteManage.java index f4c58e3..ce351ca 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/ExpertInviteManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/ExpertInviteManage.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ningdatech.basic.util.CollUtils; import com.ningdatech.pmapi.common.util.BizUtils; +import com.ningdatech.pmapi.common.util.StrUtils; import com.ningdatech.pmapi.expert.constant.ExpertAccountStatusEnum; import com.ningdatech.pmapi.expert.entity.ExpertAvoidCompany; import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; @@ -15,7 +16,7 @@ import com.ningdatech.pmapi.meeting.builder.ExpertInviteBuilder; import com.ningdatech.pmapi.meeting.entity.domain.ExpertInviteRule; import com.ningdatech.pmapi.meeting.entity.domain.Meeting; import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpert; -import com.ningdatech.pmapi.meeting.entity.dto.AvoidInfoDTO; +import com.ningdatech.pmapi.meeting.entity.dto.AvoidRuleDTO; import com.ningdatech.pmapi.meeting.entity.dto.ExpertChooseDTO; import com.ningdatech.pmapi.meeting.entity.dto.ExpertDictChooseDTO; import com.ningdatech.pmapi.meeting.entity.dto.RandomInviteRuleDTO; @@ -135,7 +136,7 @@ public class ExpertInviteManage { return expertAvoidCompanyList.stream().map(ExpertAvoidCompany::getUserId).distinct().collect(Collectors.toList()); } - private List mergeExpertIdsByCondition(RandomInviteRuleDTO rule, AvoidInfoDTO avoidInfo) { + private List mergeExpertIdsByCondition(RandomInviteRuleDTO rule, AvoidRuleDTO avoidInfo) { // 处理履职意向地 List expertIdsByIntentionRegion = expertIdsByRegion(rule); if (COLL_EMPTY.evaluate(expertIdsByIntentionRegion)) { @@ -246,34 +247,31 @@ public class ExpertInviteManage { /** * 专家抽取(随机) * - * @param avoidInfo 回避信息 + * @param avoidRule 回避信息 * @param randomRule 抽取规则 * @param appointExpertIds 指定抽取专家ID * @return 满足抽取条件的专家 * @author WendyYang **/ - public ExpertChooseDTO expertInviteByRandomRule(AvoidInfoDTO avoidInfo, + public ExpertChooseDTO expertInviteByRandomRule(AvoidRuleDTO avoidRule, RandomInviteRuleDTO randomRule, List appointExpertIds, LocalDateTime start, LocalDateTime end) { ExpertChooseDTO result = new ExpertChooseDTO(new ArrayList<>(), 0); - List expertIdsIn = mergeExpertIdsByCondition(randomRule, avoidInfo); + List expertIdsIn = mergeExpertIdsByCondition(randomRule, avoidRule); if (expertIdsIn == null) { return result; } - boolean avoid = avoidInfo != null; - boolean avoidExpert = avoid && CollUtil.isNotEmpty(avoidInfo.getExpertIds()); - boolean avoidCompany = avoid && CollUtil.isNotEmpty(avoidInfo.getAvoidUnitIdList()); + boolean avoidExpert = CollUtil.isNotEmpty(avoidRule.getExpertIds()); + boolean avoidCompany = CollUtil.isNotEmpty(avoidRule.getAvoidUnitIdList()); Set tmpAvoidCompany = new HashSet<>(); if (avoidCompany) { - List companyIds = avoidInfo.getAvoidUnitIdList(); + List companyIds = avoidRule.getAvoidUnitIdList(); for (String companyId : companyIds) { if (companyId.contains(",")) { String[] splitCompanyIds = companyId.split(","); - for (String splitCompanyId : splitCompanyIds) { - tmpAvoidCompany.add(splitCompanyId); - } + Collections.addAll(tmpAvoidCompany, splitCompanyIds); } else { tmpAvoidCompany.add(companyId); } @@ -284,14 +282,13 @@ public class ExpertInviteManage { query.notIn(!tmpAvoidCompany.isEmpty(), ExpertUserFullInfo::getCompany, tmpAvoidCompany); if (avoidCompany) { query.notExists("select 1 from expert_avoid_company eac where eac.user_id = expert_user_full_info.user_id" + - " and company_name in ({0})", CollUtils.joinByComma(avoidInfo.getAvoidUnitIdList())); + " and company_name in ({0})", CollUtils.joinByComma(avoidRule.getAvoidUnitIdList())); } // 处理专家层级 addRegionLimit(query, randomRule); - if (!expertIdsIn.isEmpty()) { if (avoidExpert) { - expertIdsIn.removeIf(w -> avoidInfo.getExpertIds().contains(w)); + expertIdsIn.removeIf(w -> avoidRule.getExpertIds().contains(w)); if (expertIdsIn.isEmpty()) { // 字典、标签、履职意向地筛选出的专家ID移除需要回避的专家ID // 如果为空则说明没有符合条件的 @@ -312,7 +309,7 @@ public class ExpertInviteManage { } query.in(ExpertUserFullInfo::getUserId, expertIdsIn); } else if (avoidExpert || CollUtil.isNotEmpty(appointExpertIds)) { - Set tempExperts = expertInviteHelper.getAvoidExpert(appointExpertIds, avoidInfo, start, end); + Set tempExperts = expertInviteHelper.getAvoidExpert(appointExpertIds, avoidRule, start, end); query.notIn(ExpertUserFullInfo::getUserId, tempExperts); } else { Set notInUserIds = expertInviteHelper.listExpertLeaveOrInvited(start, end); @@ -320,15 +317,15 @@ public class ExpertInviteManage { query.notIn(ExpertUserFullInfo::getUserId, notInUserIds); } } - List userFullInfos = expertUserFullInfoService.list(query); - if (userFullInfos.isEmpty()) { + List userInfoList = expertUserFullInfoService.list(query); + if (userInfoList.isEmpty()) { return result; } - result.setTotal(userFullInfos.size()); + Map> userGroupByUnit = CollUtils.group(userInfoList, ExpertUserFullInfo::getCompany); + result.setTotal(userInfoList.size()); // count为空表示数量校验 if (randomRule.getCount() == null || result.getTotal() >= randomRule.getCount()) { - List userFullInfoList = inviteWithoutCompany(userFullInfos, randomRule.getCount()); - result.setExperts(userFullInfoList); + result.setExperts(inviteGroupByCompany(userGroupByUnit, randomRule.getCount())); } return result; } @@ -336,39 +333,41 @@ public class ExpertInviteManage { /** * 专家替换、补充 * - * @param avoidInfo 回避信息 + * @param avoidRule 回避信息 * @param randomRule 随机抽取 - * @param meetingExperts 已抽取人员 + * @param invitedExperts 已抽取人员 * @param count 抽取数量 - * @return com.ningdatech.emapi.meeting.entity.dto.ExpertChooseDto + * @param start 会议开始时间 + * @param end 会议结束时间 + * @return {@link ExpertChooseDTO} * @author WendyYang **/ - public ExpertChooseDTO expertReplaceByRandomRule(AvoidInfoDTO avoidInfo, + public ExpertChooseDTO expertReplaceByRandomRule(AvoidRuleDTO avoidRule, RandomInviteRuleDTO randomRule, - Collection meetingExperts, + Collection invitedExperts, Integer count, LocalDateTime start, LocalDateTime end, - Long replacedExpertId) { + boolean invitedRefused) { ExpertChooseDTO result = new ExpertChooseDTO(new ArrayList<>(), 0); // 合并标签、字典 - List expertIdsIn = mergeExpertIdsByCondition(randomRule, avoidInfo); + List expertIdsIn = mergeExpertIdsByCondition(randomRule, avoidRule); if (expertIdsIn == null) { return result; } LambdaQueryWrapper query = buildBaseExpertQuery(); - query.notIn(ExpertUserFullInfo::getCompany, avoidInfo.getAvoidUnitIdList()); + query.notIn(ExpertUserFullInfo::getCompany, avoidRule.getAvoidUnitIdList()); query.notExists("select 1 from expert_avoid_company eac where eac.user_id = expert_user_full_info.user_id" + - " and company_name in ({0})", CollUtils.joinByComma(avoidInfo.getAvoidOrgIdList())); + " and company_name in ({0})", CollUtils.joinByComma(avoidRule.getAvoidOrgIdList())); // 处理专家层级 - if (ObjectUtils.allNotNull(randomRule.getExpertRegionCode(), randomRule.getExpertRegionLevel())) { + if (StrUtils.isNotBlank(randomRule.getExpertRegionCode())) { query.eq(ExpertUserFullInfo::getRegionCode, randomRule.getExpertRegionCode()); query.eq(ExpertUserFullInfo::getRegionLevel, randomRule.getExpertRegionLevel()); } if (expertIdsIn.size() > 0) { - if (CollectionUtils.isNotEmpty(avoidInfo.getExpertIds())) { - expertIdsIn.removeIf(w -> avoidInfo.getExpertIds().contains(w)); + if (CollectionUtils.isNotEmpty(avoidRule.getExpertIds())) { + expertIdsIn.removeIf(w -> avoidRule.getExpertIds().contains(w)); if (expertIdsIn.isEmpty()) { // 字典、标签、履职意向地筛选出的专家ID移除需要回避的专家ID // 如果为空则说明没有符合条件的 @@ -381,8 +380,8 @@ public class ExpertInviteManage { return result; } query.in(ExpertUserFullInfo::getUserId, expertIdsIn); - } else if (CollectionUtils.isNotEmpty(avoidInfo.getExpertIds())) { - Set notInExpertIds = expertInviteHelper.getAvoidExpert(avoidInfo.getExpertIds(), null, start, end); + } else if (CollUtil.isNotEmpty(avoidRule.getExpertIds())) { + Set notInExpertIds = expertInviteHelper.getAvoidExpert(avoidRule.getExpertIds(), null, start, end); query.notIn(ExpertUserFullInfo::getUserId, notInExpertIds); } else { Set notInUserIds = expertInviteHelper.listExpertLeaveOrInvited(start, end); @@ -394,44 +393,31 @@ public class ExpertInviteManage { if (userFullInfos.size() == 0) { return result; } - Comparator sort = Comparator.comparing(MeetingExpert::getUpdateOn).reversed(); - Map tempExpertIdsMap = BizUtils.groupFirstMap(meetingExperts, MeetingExpert::getExpertId, sort); - Map> expertIdGroupByStatus = tempExpertIdsMap.values().stream() + Map> expertGroupByStatus = invitedExperts.stream() .collect(Collectors.groupingBy(w -> ExpertAttendStatusEnum.getByCode(w.getStatus()))); // 回避同单位其他专家 List removeExpertByCompany = new ArrayList<>(); - BizUtils.notEmpty(expertIdGroupByStatus.get(ExpertAttendStatusEnum.AGREED), removeExpertByCompany::addAll); - BizUtils.notEmpty(expertIdGroupByStatus.get(ExpertAttendStatusEnum.NOTICING), removeExpertByCompany::addAll); + BizUtils.notEmpty(expertGroupByStatus.get(ExpertAttendStatusEnum.AGREED), removeExpertByCompany::addAll); + BizUtils.notEmpty(expertGroupByStatus.get(ExpertAttendStatusEnum.NOTICING), removeExpertByCompany::addAll); List removeExpertIds = new ArrayList<>(); - // 拒绝参加的不可以被再次抽中 - BizUtils.notEmpty(expertIdGroupByStatus.get(ExpertAttendStatusEnum.REFUSED), w -> { - List tempRefused = CollUtils.fieldList(w, MeetingExpert::getExpertId); - removeExpertIds.addAll(tempRefused); - }); + if (invitedRefused) { + // 拒绝参加的不可以被再次抽中 + BizUtils.notEmpty(expertGroupByStatus.get(ExpertAttendStatusEnum.REFUSED), w -> { + List tempRefused = CollUtils.fieldList(w, MeetingExpert::getExpertId); + removeExpertIds.addAll(tempRefused); + }); + } // 被取消的也不可以被再次抽中 - BizUtils.notEmpty(expertIdGroupByStatus.get(ExpertAttendStatusEnum.REMOVED), w -> { + BizUtils.notEmpty(expertGroupByStatus.get(ExpertAttendStatusEnum.REMOVED), w -> { List tempCanceled = CollUtils.fieldList(w, MeetingExpert::getExpertId); removeExpertIds.addAll(tempCanceled); }); - // 被替换之前是上述两种状态的不可被再次抽中 - BizUtils.notEmpty(expertIdGroupByStatus.get(ExpertAttendStatusEnum.REPLACED), w -> { - for (MeetingExpert me : w) { - BizUtils.notNull(me.getPreStatus(), preStatus -> { - if (ExpertAttendStatusEnum.REFUSED.eq(preStatus) || ExpertAttendStatusEnum.REMOVED.eq(preStatus)) { - removeExpertIds.add(me.getExpertId()); - } - }); - } - }); - // 不为空时表示单个专家替换否则为专家补抽 - if (replacedExpertId != null) { - removeExpertIds.add(replacedExpertId); - } List tempExpertIds = CollUtils.fieldList(removeExpertByCompany, MeetingExpert::getExpertId); // 移除确认参加、通知中的、拒绝参加、已取消 userFullInfos.removeIf(w -> tempExpertIds.contains(w.getUserId()) || removeExpertIds.contains(w.getUserId())); - result.setTotal(userFullInfos.size()); - result.setExperts(inviteWithoutCompany(userFullInfos, count)); + Map> userGroupByUnit = CollUtils.group(userFullInfos, ExpertUserFullInfo::getCompany); + result.setTotal(userGroupByUnit.size()); + result.setExperts(inviteGroupByCompany(userGroupByUnit, count)); return result; } @@ -455,26 +441,26 @@ public class ExpertInviteManage { /** * 每个单位只抽取一人 * - * @param expertGroupByCompany 需要抽取的人 - * @param count 抽取数量 + * @param expertGroupByUnit 需要抽取的人 + * @param count 抽取数量 * @return java.util.List * @author WendyYang **/ - private List inviteGroupByCompany(Map> expertGroupByCompany, Integer count) { - if (MapUtils.isEmpty(expertGroupByCompany)) { + private List inviteGroupByCompany(Map> expertGroupByUnit, Integer count) { + if (MapUtils.isEmpty(expertGroupByUnit)) { return Collections.emptyList(); } List> meetingExperts = selectMeetingExpertByCount(); if (meetingExperts.isEmpty()) { - return expertGroupByCompany.values().stream() + return expertGroupByUnit.values().stream() .map(expertUsers -> expertUsers.get(RandomUtils.nextInt(0, expertUsers.size()))) .limit(count).collect(Collectors.toList()); } else { List result = new ArrayList<>(); - List keySet = new ArrayList<>(expertGroupByCompany.keySet()); + List keySet = new ArrayList<>(expertGroupByUnit.keySet()); for (int i = 0; i < count; i++) { String key = keySet.get(RandomUtils.nextInt(0, keySet.size())); - List expertUserFullInfos = expertGroupByCompany.get(key); + List expertUserFullInfos = expertGroupByUnit.get(key); for (List expertList : meetingExperts) { List tempList = expertUserFullInfos.stream() .filter(w -> expertList.stream().noneMatch(expert -> expert.getExpertId().equals(w.getUserId()))) @@ -547,12 +533,13 @@ public class ExpertInviteManage { * 专家抽取(会议创建时抽取) * * @param randomRules 随机抽取规则 - * @param avoid 回避信息 + * @param avoidRuled 回避信息 + * @param meeting 会议信息 * @author WendyYang **/ - public void expertRandomInviteByMeetingCreate(Meeting meeting, - List randomRules, - AvoidInfoDTO avoid) { + public void expertInviteByMeetingCreate(Meeting meeting, + List randomRules, + AvoidRuleDTO avoidRuled) { List expertInserts = new ArrayList<>(); // 处理随机抽取规则 if (CollectionUtils.isNotEmpty(randomRules)) { @@ -562,7 +549,7 @@ public class ExpertInviteManage { LocalDateTime startTime = meeting.getStartTime(); LocalDateTime endTime = meeting.getEndTime(); randomRules.forEach(rule -> { - ExpertChooseDTO tempExperts = expertInviteByRandomRule(avoid, rule, choosedExpertIds, startTime, endTime); + ExpertChooseDTO tempExperts = expertInviteByRandomRule(avoidRuled, rule, choosedExpertIds, startTime, endTime); expertsByRandom.add(tempExperts); choosedExpertIds.addAll(CollUtils.fieldList(tempExperts.getExperts(), ExpertUserFullInfo::getUserId)); randoms.add(getExpertInviteRule(rule, meeting.getId())); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/MeetingManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/MeetingManage.java index a92d1d4..f3f2e67 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/MeetingManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/MeetingManage.java @@ -140,6 +140,29 @@ public class MeetingManage { } } + public void continueInvite(Long meetingId) { + String key = "CONTINUE_INVITE:" + meetingId; + if (!distributedLock.lock(key, RETRY_TIMES)) { + throw BizException.wrap("已进行续抽,请勿重复点击"); + } + try { + Meeting meeting = meetingService.getById(meetingId); + if (!meeting.getInviteStatus()) { + throw BizException.wrap("该会议正在抽取专家,暂无法续抽"); + } + if (!MeetingStatusEnum.NORMAL.eq(meeting.getStatus())) { + throw BizException.wrap("续抽失败,请刷新后重试"); + } + boolean invitedContinue = meetingManageHelper.checkCouldBeInvitedContinue(meetingId); + if (!invitedContinue) { + throw BizException.wrap("抽取人员数量已满足抽取规则"); + } + + } finally { + distributedLock.releaseLock(key); + } + } + @Transactional(rollbackFor = Exception.class) public void expertInviteByCreate(ExpertInviteReq req) { String key = INVITED_RULE_CREATE + req.getMeetingId(); @@ -151,7 +174,7 @@ public class MeetingManage { if (ExpertInviteTypeEnum.RANDOM.eq(req.getInviteType())) { List randomRules = req.getRandomRules(); Assert.notEmpty(randomRules, "随机抽取规则不能为空"); - AvoidInfoDTO avoidInfo = req.getAvoidRule(); + AvoidRuleDTO avoidInfo = req.getAvoidRule(); Assert.notNull(avoidInfo, "回避信息不能为空"); // 随机抽取的话则需进行抽取数量校验 ExpertCountOnChangeVO countOnChange = expertCountOnChange(req); @@ -163,23 +186,21 @@ public class MeetingManage { Integer inviteCount = randomRules.get(i).getCount(); Assert.isTrue(checkCount >= inviteCount, "可供抽取的专家数量不足"); } - expertInviteManage.expertRandomInviteByMeetingCreate(meeting, randomRules, avoidInfo); + expertInviteManage.expertInviteByMeetingCreate(meeting, randomRules, avoidInfo); expertInviteTask.addInviteExpertTaskByMeetingCreate(meeting.getId(), 5); LambdaUpdateWrapper update = Wrappers.lambdaUpdate(Meeting.class); update.set(Meeting::getInviteStatus, false); update.eq(Meeting::getId, meeting.getId()); meetingService.update(update); // 回避规则 - if (avoidInfo != null) { - ExpertInviteAvoidRule avoidRule = new ExpertInviteAvoidRule(); - avoidRule.setMeetingId(meeting.getId()); - // 未传值时设置为0 表示不限制周参与次数 - avoidRule.setWeekInviteCount(ObjectUtil.defaultIfNull(avoidRule.getWeekInviteCount(), 0)); - avoidRule.setAvoidOrgIds(CollUtils.joinByComma(avoidInfo.getAvoidOrgIdList())); - avoidRule.setAvoidUnitIds(CollUtils.joinByComma(avoidInfo.getAvoidUnitIdList())); - avoidRule.setAvoidExpertIds(CollUtils.joinByComma(avoidInfo.getExpertIds())); - inviteAvoidRuleService.save(avoidRule); - } + ExpertInviteAvoidRule avoidRule = new ExpertInviteAvoidRule(); + avoidRule.setMeetingId(meeting.getId()); + // 未传值时设置为0 表示不限制周参与次数 + avoidRule.setWeekInviteCount(ObjectUtil.defaultIfNull(avoidRule.getWeekInviteCount(), 0)); + avoidRule.setAvoidOrgIds(CollUtils.joinByComma(avoidInfo.getAvoidOrgIdList())); + avoidRule.setAvoidUnitIds(CollUtils.joinByComma(avoidInfo.getAvoidUnitIdList())); + avoidRule.setAvoidExpertIds(CollUtils.joinByComma(avoidInfo.getExpertIds())); + inviteAvoidRuleService.save(avoidRule); } else { // 指定邀请 AppointInviteRuleDTO appointRule = req.getAppointRule(); @@ -449,7 +470,7 @@ public class MeetingManage { } result.getRandomRules().add(randomRule); }); - AvoidInfoDTO avoidInfo = inviteAvoidRuleService.getAvoidInfoDto(meetingId); + AvoidRuleDTO avoidInfo = inviteAvoidRuleService.getAvoidInfoDto(meetingId); AvoidInfoVO vo = new AvoidInfoVO(); vo.setAvoidOrgIds(avoidInfo.getAvoidOrgIdList()); vo.setAvoidUnitIds(avoidInfo.getAvoidUnitIdList()); @@ -469,75 +490,6 @@ public class MeetingManage { return result; } - public void expertRemove(ExpertRemoveReq po) { - LambdaUpdateWrapper update = Wrappers.lambdaUpdate(MeetingExpert.class) - .eq(MeetingExpert::getId, po.getExpertMeetingId()) - .set(MeetingExpert::getStatus, ExpertAttendStatusEnum.REMOVED.getCode()); - meetingExpertService.update(update); - } - - @Transactional(rollbackFor = Exception.class) - public void expertReplace(ExpertRemoveReq po) { - MeetingExpert meetingExpert = meetingExpertService.getById(po.getExpertMeetingId()); - ExpertUserFullInfo expertFullInfo; - Long ruleId = 0L; - Meeting meeting = meetingService.getById(po.getMeetingId()); - if (po.getExpertId() != null) { - // 指定邀请替换 - List userInfos = meetingManageHelper.appointExpertCheck(po.getMeetingId(), Collections.singletonList(po.getExpertId())); - expertFullInfo = userInfos.get(0); - } else { - List inviteRules = inviteRuleService.listByMeetingId(po.getMeetingId()); - // 邀请规则 - RandomInviteRuleDTO randomInviteRuleDto = null; - for (ExpertInviteRule rule : inviteRules) { - if (rule.getInviteType().equals(ExpertInviteTypeEnum.RANDOM.getCode()) && - rule.getId().equals(meetingExpert.getRuleId())) { - randomInviteRuleDto = JSON.parseObject(rule.getInviteRule(), RandomInviteRuleDTO.class); - ruleId = rule.getId(); - break; - } - } - // 回避规则 - AvoidInfoDTO avoidInfoDto = meetingManageHelper.getAvoidInfoDto(po.getMeetingId()); - // 添加回避该替换的专家 - List expertIds = avoidInfoDto.getExpertIds(); - if (CollUtil.isEmpty(expertIds)) { - expertIds = new ArrayList<>(); - } - expertIds.add(meetingExpert.getExpertId()); - avoidInfoDto.setExpertIds(expertIds); - meetingManageHelper.saveAvoidInfo(po.getMeetingId(), avoidInfoDto.getExpertIds()); - - List meetingExperts = meetingExpertService.listByMeetingId(po.getMeetingId()); - ExpertChooseDTO expertChooseDto = expertInviteManage.expertReplaceByRandomRule(avoidInfoDto, randomInviteRuleDto, - meetingExperts, 1, meeting.getStartTime(), meeting.getEndTime(), meetingExpert.getExpertId()); - Assert.isTrue(expertChooseDto.getTotal() > 0, "暂无专家可供替换"); - expertFullInfo = expertChooseDto.getExperts().get(0); - expertInviteTask.addInviteExpertTask(po.getMeetingId()); - } - LambdaUpdateWrapper update = Wrappers.lambdaUpdate(MeetingExpert.class) - .eq(MeetingExpert::getId, po.getExpertMeetingId()) - .set(MeetingExpert::getUpdateOn, LocalDateTime.now()) - .set(MeetingExpert::getPreStatus, meetingExpert.getStatus()) - .set(MeetingExpert::getStatus, ExpertAttendStatusEnum.REPLACED.getCode()); - meetingExpertService.update(update); - MeetingExpert me; - if (po.getExpertId() == null) { - me = ExpertInviteBuilder.getExpertByRandom(po.getMeetingId(), expertFullInfo, ruleId); - } else { - me = ExpertInviteBuilder.getExpertByAppoint(po.getMeetingId(), expertFullInfo, ruleId); - } - me.setStatus(ExpertAttendStatusEnum.NOTICING.getCode()); - me.setPreId(po.getExpertMeetingId()); - yxtCallOrSmsHelper.callByMeetingExperts(meeting, Collections.singletonList(me)); - meetingExpertService.save(me); - // 发送专家替换短信 TODO - // String meetingType = dictionaryCache.getByCode(meeting.getType()).getName(); - // SendSmsContext context = YxtSmsContextBuilder.smsToExpertByReplace(meeting, meetingExpert, meetingType); - // yxtCallOrSmsHelper.sendSms(context); - } - public void batchAppointExperts(BatchAppointExpertsReq req) { Long meetingId = req.getMeetingId(); String key = "BATCH_APPOINT_EXPERT:" + meetingId; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/service/IExpertInviteAvoidRuleService.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/service/IExpertInviteAvoidRuleService.java index 24bb363..7b25003 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/service/IExpertInviteAvoidRuleService.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/service/IExpertInviteAvoidRuleService.java @@ -2,7 +2,7 @@ package com.ningdatech.pmapi.meeting.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ningdatech.pmapi.meeting.entity.domain.ExpertInviteAvoidRule; -import com.ningdatech.pmapi.meeting.entity.dto.AvoidInfoDTO; +import com.ningdatech.pmapi.meeting.entity.dto.AvoidRuleDTO; /** *

@@ -23,6 +23,6 @@ public interface IExpertInviteAvoidRuleService extends IService { * 查询专家的参与状态 * * @param expertId 专家ID - * @param status 状态{@link MeetingStatus.Expert} + * @param status 状态 * @param meetingIds 会议ID * @return 会议参加状态统计 * @author WendyYang @@ -35,7 +35,7 @@ public interface IMeetingExpertService extends IService { List listByExpertIdAndStatus(Long expertId, Integer status, List meetingIds); /** - * 查询每个事物的确认进度 + * 查询每个会议的确认进度 * * @param meetingIds 事务ID * @return 确认进度 @@ -132,4 +132,15 @@ public interface IMeetingExpertService extends IService { **/ List listExpertLastByMeetingIds(Collection meetingIds); + /** + * 查询会议的所有被抽取人最后一条记录 + * + * @param meetingId 会议ID + * @return 抽取记录 + * @author WendyYang + **/ + default List listExpertLastByMeetingId(Long meetingId) { + return listExpertLastByMeetingIds(Collections.singletonList(meetingId)); + } + } \ No newline at end of file diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/service/impl/ExpertInviteAvoidRuleServiceImpl.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/service/impl/ExpertInviteAvoidRuleServiceImpl.java index 0fed622..f639ad6 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/service/impl/ExpertInviteAvoidRuleServiceImpl.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/service/impl/ExpertInviteAvoidRuleServiceImpl.java @@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ningdatech.pmapi.common.util.BizUtils; import com.ningdatech.pmapi.common.util.StrUtils; import com.ningdatech.pmapi.meeting.entity.domain.ExpertInviteAvoidRule; -import com.ningdatech.pmapi.meeting.entity.dto.AvoidInfoDTO; +import com.ningdatech.pmapi.meeting.entity.dto.AvoidRuleDTO; import com.ningdatech.pmapi.meeting.mapper.ExpertInviteAvoidRuleMapper; import com.ningdatech.pmapi.meeting.service.IExpertInviteAvoidRuleService; import org.springframework.stereotype.Service; @@ -30,12 +30,12 @@ public class ExpertInviteAvoidRuleServiceImpl extends ServiceImpl> INVITE_MAP = new ConcurrentHashMap<>(); + public ExpertInviteTask currProxy() { + return (ExpertInviteTask) AopContext.currentProxy(); + } + @PostConstruct public void initTask() { if (!properties.getEnable()) { log.warn("随机邀请已关闭……"); return; } -// initInviteTaskByStart(); + initInviteTaskAfterAppStarted(); } /** * 项目重启之后重新初始化邀请任务 */ - private void initInviteTaskByStart() { - Set meetingIds = cachePlusOps.sMembers(CACHE_KEY); - if (meetingIds == null || meetingIds.isEmpty()) { + private void initInviteTaskAfterAppStarted() { + Map meetingIdMap = cachePlusOps.hGetAll(CACHE_KEY); + if (MapUtils.isEmpty(meetingIdMap)) { + log.info("暂无需要初始化的抽取会议信息"); return; } - for (Object meetingId : meetingIds) { - addInviteExpertTask(Convert.toLong(meetingId), true, properties.getInviteDelay()); + for (MeetingInviteCacheDTO cache : meetingIdMap.values()) { + addInviteExpertTask(cache.getMeetingId(), true, properties.getInviteDelay(), cache.getInvitedRefused()); } } @@ -123,25 +122,27 @@ public class ExpertInviteTask { * @return boolean * @author WendyYang **/ - private boolean inviteCheck(Long meetingId) { - List expertInviteRules = inviteRuleService.listByMeetingId(meetingId); - Function groupKey = w -> ExpertInviteTypeEnum.getByCode(w.getInviteType()); - Map> groupByType = CollUtils.group(expertInviteRules, groupKey); - List randomRules = groupByType.get(ExpertInviteTypeEnum.RANDOM); - if (CollUtil.isEmpty(randomRules)) { - return false; + private boolean inviteCountCheck(Long meetingId) { + Map ruleMap = inviteRuleService.randomRuleByMeetingId(meetingId); + if (ruleMap.isEmpty()) { + return Boolean.FALSE; } - Map ruleMap = CollUtils.listToMap(randomRules, ExpertInviteRule::getId); LambdaQueryWrapper query = Wrappers.lambdaQuery(MeetingExpert.class) + .select(MeetingExpert::getRuleId, MeetingExpert::getStatus) .in(MeetingExpert::getRuleId, ruleMap.keySet()) .in(MeetingExpert::getStatus, ExpertAttendStatusEnum.AGREED.getCode()); - List meetingExperts = meetingExpertService.list(query); - int totalCount = CollUtils.sum(randomRules, ExpertInviteRule::getInviteCount); - boolean needed = totalCount > meetingExperts.size(); - if (!needed) { - cancelByMeetingId(meetingId); + List experts = meetingExpertService.list(query); + if (experts.isEmpty()) { + return Boolean.FALSE; + } + Map cntMap = CollUtils.groupCount(experts, MeetingExpert::getRuleId); + for (Map.Entry entry : ruleMap.entrySet()) { + Long agreeCnt = cntMap.getOrDefault(entry.getKey(), 0L); + if (agreeCnt < entry.getValue().getCount()) { + return Boolean.FALSE; + } } - return needed; + return Boolean.TRUE; } /** @@ -151,9 +152,8 @@ public class ExpertInviteTask { * @author WendyYang **/ public void addInviteExpertTask(Long meetingId) { - boolean contains = INVITE_MAP.containsKey(meetingId); - if (!contains) { - addInviteExpertTask(meetingId, false, properties.getInviteDelay()); + if (!INVITE_MAP.containsKey(meetingId)) { + addInviteExpertTask(meetingId, false, properties.getInviteDelay(), false); log.info("重置会议的随机抽取状态:{}", meetingId); LambdaUpdateWrapper update = Wrappers.lambdaUpdate(Meeting.class); update.set(Meeting::getInviteStatus, false); @@ -170,17 +170,19 @@ public class ExpertInviteTask { * @param meetingId 会议ID * @param checked 是否前置校验 * @param delayedMinutes 延迟执行时间 + * @param invitedRefused 是否可以邀请被拒绝的专家 * @author WendyYang **/ - public void addInviteExpertTask(Long meetingId, boolean checked, int delayedMinutes) { - if (checked && !inviteCheck(meetingId)) { + public void addInviteExpertTask(Long meetingId, boolean checked, int delayedMinutes, boolean invitedRefused) { + if (checked && !inviteCountCheck(meetingId)) { + // 如果抽取数量满足直接返回 return; } Instant startTime = LocalDateTime.now().plusMinutes(delayedMinutes).atZone(ZoneId.systemDefault()).toInstant(); ScheduledFuture future = scheduler.scheduleAtFixedRate(() -> { ExpertInviteTask bean = SpringContextHolder.getBean(ExpertInviteTask.class); try { - bean.invite(meetingId); + bean.invite(meetingId, invitedRefused); } catch (Exception e) { log.error("执行专家邀请任务异常:{}", meetingId, e); } @@ -189,53 +191,55 @@ public class ExpertInviteTask { log.info("添加专家抽取后台任务:{}", meetingId); } + /** + * 创建会议时添加抽取任务 + * + * @param meetingId 会议ID + * @param delayedMinutes 延迟时间 + * @author WendyYang + **/ public void addInviteExpertTaskByMeetingCreate(Long meetingId, int delayedMinutes) { Assert.isTrue(properties.getEnable(), "随机邀请已关闭"); - addInviteExpertTask(meetingId, false, delayedMinutes); + addInviteExpertTask(meetingId, false, delayedMinutes, false); cachePlusOps.sAdd(CACHE_KEY, meetingId); } @Transactional(rollbackFor = Exception.class) - public void invite(Long meetingId) { + public void invite(Long meetingId, Boolean invitedRefused) { log.info("开始进行专家后台抽取:{}", meetingId); Meeting meeting = meetingService.getById(meetingId); if (meeting.getStartTime().isBefore(LocalDateTime.now())) { - // 会议开始结束随机抽取 - cancelByMeetingId(meetingId); log.info("会议已开始停止抽取:{}", meeting); + cancelByMeetingId(meetingId); return; } // 随机邀请规则 Map ruleMap = inviteRuleService.randomRuleByMeetingId(meetingId); // 回避规则 - AvoidInfoDTO avoidInfoDto = expertInviteAvoidRuleService.getAvoidInfoDto(meetingId); + AvoidRuleDTO avoidRule = inviteAvoidRuleService.getAvoidInfoDto(meetingId); // 还需要抽取的规则数量 AtomicInteger notIgnoreCnt = new AtomicInteger(ruleMap.size()); AtomicInteger notSupportCnt = new AtomicInteger(0); ruleMap.forEach((ruleId, value) -> { - List singletonList = Collections.singletonList(meetingId); - List tempExperts = meetingExpertService.listExpertLastByMeetingIds(singletonList); - Map expertMap = CollUtils.listToMap(tempExperts, MeetingExpert::getExpertId); - Map replacedMap = expertMap.values().stream().filter(w -> w.getPreId() > 0) - .collect(Collectors.toMap(MeetingExpert::getPreId, w -> w)); - Map countMap = countByAgree(expertMap, replacedMap); - // 已确认参加、通话中数量 + List tmpExperts = meetingExpertService.listExpertLastByMeetingId(meetingId); + Map expertMap = CollUtils.listToMap(tmpExperts, MeetingExpert::getExpertId); + // 统计通知中与同意参加专家数量 + Map countMap = countByAgree(expertMap); ExpertCntBO cnt = countMap.getOrDefault(ruleId, ExpertCntBO.zeroInit()); - int tempCurrent = cnt.getAgreeCnt() + cnt.getNoticeCnt(); - if (tempCurrent == value.getCount()) { + int wouldAttendCnt = cnt.getAgreeCnt() + cnt.getNoticeCnt(); + if (wouldAttendCnt == value.getCount()) { if (cnt.getAgreeCnt().equals(value.getCount())) { notIgnoreCnt.decrementAndGet(); } return; } - int currInviteCnt = value.getCount() - tempCurrent; - ExpertChooseDTO expertChoose = expertInviteManage.expertReplaceByRandomRule(avoidInfoDto, value, - expertMap.values(), currInviteCnt, meeting.getStartTime(), meeting.getEndTime(), null); + int needInviteCnt = value.getCount() - wouldAttendCnt; + ExpertChooseDTO expertChoose = expertInviteManage.expertReplaceByRandomRule(avoidRule, value, + tmpExperts, needInviteCnt, meeting.getStartTime(), meeting.getEndTime(), invitedRefused); if (expertChoose.getTotal() > 0) { List expertMeetings = CollUtils.convert(expertChoose.getExperts(), w -> { MeetingExpert expert = ExpertInviteBuilder.getExpertByRandom(meetingId, w, ruleId); - expert.setPreStatus(ExpertAttendStatusEnum.NOTICING.getCode()); expert.setStatus(ExpertAttendStatusEnum.NOTICING.getCode()); return expert; }); @@ -276,7 +280,7 @@ public class ExpertInviteTask { //================================================================================================================== - private Map countByAgree(Map expertMap, Map replacedMap) { + private Map countByAgree(Map expertMap) { return expertMap.entrySet().stream() .collect(Collectors.groupingBy(w -> w.getValue().getRuleId(), Collectors.collectingAndThen(Collectors.mapping(Map.Entry::getValue, Collectors.toList()), w -> { @@ -286,11 +290,6 @@ public class ExpertInviteTask { cnt.incrAgreeCnt(); } else if (ExpertAttendStatusEnum.NOTICING.eq(expert.getStatus())) { cnt.incrNoticeCnt(); - } else if (ExpertAttendStatusEnum.REPLACED.eq(expert.getStatus())) { - MeetingExpert replacedExpert = replacedMap.get(expert.getId()); - if (replacedExpert != null && ExpertAttendStatusEnum.AGREED.eq(replacedExpert.getStatus())) { - cnt.incrAgreeCnt(); - } } } return cnt; diff --git a/pmapi/src/main/resources/application-dev.yml b/pmapi/src/main/resources/application-dev.yml index 14b6ecd..18fcf60 100644 --- a/pmapi/src/main/resources/application-dev.yml +++ b/pmapi/src/main/resources/application-dev.yml @@ -15,7 +15,7 @@ spring: timeout: 5000 host: 47.98.125.47 port: 26379 - database: 0 + database: 4 password: Ndkj1234 jedis: pool: