@@ -26,7 +26,9 @@ public enum MeetingReviewTypeEnum { | |||
ACCEPTANCE_SCHEME_REVIEW("验收方案评审", "3"), | |||
DEPT_JOIN_REVIEW("部门联审", "4"); | |||
DEPT_JOIN_REVIEW("部门联审", "4"), | |||
FAIRNESS_REVIEW( "公平性审查","5"); | |||
private final String value; | |||
private final String code; | |||
@@ -851,7 +851,8 @@ public class MeetingManage { | |||
public PageVo<MeetingReviewProjectVO> optionProject(MeetingOptionProjectReq req) { | |||
String meetingType = req.getMeetingType(); | |||
LambdaQueryWrapper<Project> query = Wrappers.lambdaQuery(Project.class); | |||
LambdaQueryWrapper<Project> query = Wrappers.lambdaQuery(Project.class) | |||
.eq(Project::getNewest, Boolean.TRUE); | |||
switch (MeetingReviewTypeEnum.getByCode(meetingType)) { | |||
case PRELIMINARY_SCHEME_REVIEW: | |||
buildOptionProjectQuery(query, meetingType, ProjectStatusEnum.PRE_APPLYING); | |||
@@ -865,6 +866,8 @@ public class MeetingManage { | |||
case DEPT_JOIN_REVIEW: | |||
buildOptionProjectQuery(query, meetingType, ProjectStatusEnum.DEPARTMENT_JOINT_REVIEW); | |||
break; | |||
case FAIRNESS_REVIEW: | |||
break; | |||
default: | |||
return PageVo.empty(); | |||
} | |||
@@ -6,25 +6,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.ningdatech.basic.util.StrPool; | |||
import com.ningdatech.pmapi.common.util.StrUtils; | |||
import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; | |||
import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService; | |||
import com.ningdatech.pmapi.meeting.entity.config.WebProperties; | |||
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.RandomInviteRuleDTO; | |||
import com.ningdatech.pmapi.meeting.entity.dto.YxtCallBackDTO; | |||
import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | |||
import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertInviteTypeEnum; | |||
import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; | |||
import com.ningdatech.pmapi.meeting.service.IExpertInviteRuleService; | |||
import com.ningdatech.pmapi.meeting.service.IMeetingExpertService; | |||
import com.ningdatech.pmapi.meeting.service.IMeetingService; | |||
import com.ningdatech.pmapi.meta.helper.DictionaryCache; | |||
import com.ningdatech.pmapi.sms.constant.VoiceSmsTemplateConst; | |||
import com.ningdatech.pmapi.sms.utils.DateUtil; | |||
import com.ningdatech.yxt.entity.SysMsgRecordDetail; | |||
import com.ningdatech.yxt.model.cmd.SendSmsCmd.SendSmsContext; | |||
import com.ningdatech.yxt.service.ISysMsgRecordDetailService; | |||
import lombok.AllArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
@@ -61,11 +51,7 @@ public class ExpertCallResultRewriteTask { | |||
private final ThreadPoolTaskScheduler scheduler; | |||
private final IMeetingExpertService meetingExpertService; | |||
private final IExpertInviteRuleService inviteRuleService; | |||
private final IMeetingService meetingService; | |||
private final ISysMsgRecordDetailService msgRecordDetailService; | |||
private final DictionaryCache dictionaryCache; | |||
private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | |||
private final IExpertUserFullInfoService userFullInfoService; | |||
private final static int MINUTES_CALL_RESULT_FEEDBACK = 15; | |||
private static final String AGREE_KEY = "1"; | |||
@@ -140,38 +126,6 @@ public class ExpertCallResultRewriteTask { | |||
} | |||
} | |||
meetingExpertService.updateBatchById(updates); | |||
if (agrees.size() > 0) { | |||
obtainCallBackAfterMeetingCanceled(agrees); | |||
} | |||
} | |||
private void sendAgreeNotice(MeetingExpert expert) { | |||
try { | |||
Meeting meeting = meetingService.getById(expert.getMeetingId()); | |||
if (Objects.isNull(meeting)) { | |||
return; | |||
} | |||
ExpertUserFullInfo expertUserFullInfo = userFullInfoService.getByUserId(expert.getExpertId()); | |||
String expertName = null; | |||
if (Objects.nonNull(expertUserFullInfo)) { | |||
expertName = expertUserFullInfo.getExpertName(); | |||
} | |||
String smsContent = String.format(VoiceSmsTemplateConst.EXPERT_AGREE_ATTEND_TEMPLATE, | |||
meeting.getHoldOrg(), | |||
expertName, | |||
meeting.getName(), | |||
meeting.getStartTime().format(DateUtil.DTF_YMD_HM), | |||
meeting.getMeetingAddress(), | |||
meeting.getConnecter(), | |||
meeting.getContact(), | |||
WebProperties.webUrl); | |||
SendSmsContext context = new SendSmsContext(); | |||
context.setContent(smsContent); | |||
context.setReceiveNumber(expert.getMobile()); | |||
yxtCallOrSmsHelper.sendSms(context); | |||
} catch (Exception e) { | |||
log.info("发送专家会议接受通知短信失败:{}", JSONObject.toJSONString(expert)); | |||
} | |||
} | |||
private static Optional<Integer> getStatusByMsgRecordDetail(SysMsgRecordDetail mrd, int minutes, LocalDateTime createOn) { | |||
@@ -217,33 +171,4 @@ public class ExpertCallResultRewriteTask { | |||
return Optional.of(status.getCode()); | |||
} | |||
/** | |||
* 会议取消之后拿到回调结果的话需要发送取消短信 | |||
**/ | |||
private void obtainCallBackAfterMeetingCanceled(List<MeetingExpert> experts) { | |||
/*List<Long> meetingIds = CollUtils.fieldList(experts, MeetingExpert::getMeetingId); | |||
LambdaQueryWrapper<Meeting> mQuery = Wrappers.lambdaQuery(Meeting.class) | |||
.eq(Meeting::getStatus, Manager.CANCELED.getCode()) | |||
.in(Meeting::getId, meetingIds); | |||
Map<Long, Meeting> meetingMap = CollUtils.listToMap(meetingService.list(mQuery), Meeting::getId); | |||
if (meetingMap.size() > 0) { | |||
Map<Meeting, List<MeetingExpert>> expertList = new HashMap<>(16); | |||
experts.forEach(w -> { | |||
Meeting meeting = meetingMap.get(w.getMeetingId()); | |||
if (meeting == null) { | |||
return; | |||
} | |||
List<MeetingExpert> list = expertList.computeIfAbsent(meeting, k -> new ArrayList<>()); | |||
list.add(w); | |||
}); | |||
if (!expertList.isEmpty()) { | |||
expertList.forEach((m, mes) -> { | |||
String meetingType = dictionaryCache.getByCode(m.getType()).getName(); | |||
List<SendSmsContext> contexts = YxtSmsContextBuilder.smsToExpertByCancelMeeting(m, mes, meetingType); | |||
yxtCallOrSmsHelper.sendSms(contexts); | |||
}); | |||
} | |||
}*/ | |||
} | |||
} |
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.ningdatech.basic.util.SpringUtils; | |||
import com.ningdatech.cache.model.cache.CacheHashKey; | |||
import com.ningdatech.cache.repository.CachePlusOps; | |||
import com.ningdatech.pmapi.common.util.SpringContextHolder; | |||
@@ -16,8 +17,10 @@ import com.ningdatech.pmapi.meeting.entity.dto.ExpertChooseDTO; | |||
import com.ningdatech.pmapi.meeting.entity.dto.InviteCacheDTO; | |||
import com.ningdatech.pmapi.meeting.entity.dto.RandomInviteRuleDTO; | |||
import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | |||
import com.ningdatech.pmapi.meeting.entity.req.ConfirmedRosterReq; | |||
import com.ningdatech.pmapi.meeting.helper.MeetingCallOrMsgHelper; | |||
import com.ningdatech.pmapi.meeting.manage.ExpertInviteManage; | |||
import com.ningdatech.pmapi.meeting.manage.MeetingManage; | |||
import com.ningdatech.pmapi.meeting.service.IExpertInviteAvoidRuleService; | |||
import com.ningdatech.pmapi.meeting.service.IExpertInviteRuleService; | |||
import com.ningdatech.pmapi.meeting.service.IMeetingExpertService; | |||
@@ -275,6 +278,13 @@ public class ExpertRandomInviteTask { | |||
currProxy().cancelByMeetingId(meetingId); | |||
meetingCallOrMsgHelper.sendInviteStopMsg(meeting.getCreateBy(), meetingId, meeting.getName()); | |||
} | |||
if (notIgnoreCnt.get() == 0 && notSupportCnt.get() == 0) { | |||
MeetingManage meetingManage = SpringUtils.getBean(MeetingManage.class); | |||
ConfirmedRosterReq req = new ConfirmedRosterReq(); | |||
req.setReconfirmed(false); | |||
req.setMeetingId(meetingId); | |||
meetingManage.confirmedRoster(req); | |||
} | |||
} | |||
@Transactional(rollbackFor = Exception.class) | |||
@@ -1,93 +0,0 @@ | |||
//package com.ningdatech.pmapi.meeting.task; | |||
// | |||
//import com.alibaba.fastjson.JSONObject; | |||
//import com.baomidou.mybatisplus.core.toolkit.StringUtils; | |||
//import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
//import com.ningdatech.pmapi.meeting.builder.YxtSmsContextBuilder; | |||
//import com.ningdatech.pmapi.meeting.entity.domain.ExpertInviteRule; | |||
//import com.ningdatech.pmapi.meeting.entity.domain.Meeting; | |||
//import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatus; | |||
//import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatus; | |||
//import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; | |||
//import com.ningdatech.pmapi.meeting.service.IExpertInviteRuleService; | |||
//import com.ningdatech.pmapi.meeting.service.IMeetingExpertService; | |||
//import com.ningdatech.pmapi.meeting.service.IMeetingService; | |||
//import lombok.AllArgsConstructor; | |||
//import lombok.extern.slf4j.Slf4j; | |||
//import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; | |||
//import org.springframework.stereotype.Component; | |||
// | |||
//import javax.annotation.PostConstruct; | |||
//import java.time.Duration; | |||
//import java.time.Instant; | |||
//import java.time.temporal.ChronoUnit; | |||
//import java.util.HashSet; | |||
//import java.util.List; | |||
//import java.util.Objects; | |||
//import java.util.Set; | |||
// | |||
///** | |||
// * @author liuxinxin | |||
// * @date 2023/2/2 上午9:57 | |||
// */ | |||
// | |||
//@Slf4j | |||
//@Component | |||
//@AllArgsConstructor | |||
//public class MeetingInviteCompleteNoticeTask { | |||
// | |||
// private final RandomInviteProperties randomInviteProperties; | |||
// private final IMeetingService meetingService; | |||
// private final IMeetingExpertService meetingExpertService; | |||
// private final ThreadPoolTaskScheduler scheduler; | |||
// private final RedisUtils redisUtils; | |||
// private final static String MEETING_INVITE_COMPLETE_NOTICED_MEETING_ID_CACHE_KEY = "MEETING_INVITE_COMPLETE_NOTICED_MEETING_ID_CACHE_KEY"; | |||
// private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | |||
// private final IExpertInviteRuleService iExpertInviteRuleService; | |||
// | |||
// @PostConstruct | |||
// public void initTask() { | |||
// Instant startTime = Instant.now().plus(randomInviteProperties.getMeetingInviteCompleteNoticeRate(), ChronoUnit.MINUTES); | |||
// // 处理电话结果回填 | |||
// scheduler.scheduleAtFixedRate(this::meetingInviteCompleteNotice, startTime, Duration.ofMinutes(randomInviteProperties.getResultRewriteFixedRate())); | |||
// } | |||
// | |||
// public void meetingInviteCompleteNotice() { | |||
// log.info("开始执行抽取完成通知:{}", Thread.currentThread().getName()); | |||
// List<Meeting> meetingIdList = meetingService.list(Wrappers.lambdaQuery(Meeting.class) | |||
// .eq(Meeting::getStatus, MeetingStatus.Manager.UNCOMPLETED.getCode()) | |||
// .eq(Meeting::getSendMeetingNotice, false) | |||
// .eq(Meeting::getStopRandomInvite, true)); | |||
// | |||
// Set<Long> completeNoticedMeetingIdList = getCompleteNoticedMeetingIdList(); | |||
// for (Meeting meeting : meetingIdList) { | |||
// Long meetingId = meeting.getId(); | |||
// if (completeNoticedMeetingIdList.add(meetingId)) { | |||
// List<ExpertInviteRule> expertInviteRules = iExpertInviteRuleService.listByMeetingId(meetingId); | |||
// if (expertInviteRules.size() == 0) { | |||
// return; | |||
// } | |||
// int noticeCount = meetingExpertService.countExpertByStatusAndMeetingId(ExpertAttendStatus.NOTICING, meetingId, null); | |||
// if (noticeCount == 0) { | |||
// redisUtils.set(MEETING_INVITE_COMPLETE_NOTICED_MEETING_ID_CACHE_KEY, JSONObject.toJSONString(completeNoticedMeetingIdList), 24 * 60 * 60); | |||
// if (StringUtils.isNotBlank(meeting.getContact()) && StringUtils.isNotBlank(meeting.getConnecter())) { | |||
// SendSmsCmd.SendSmsContext context = YxtSmsContextBuilder.meetingInviteCompleteNotice(meeting); | |||
// yxtCallOrSmsHelper.sendSms(context); | |||
// } | |||
// } | |||
// } | |||
// } | |||
// } | |||
// | |||
// private Set<Long> getCompleteNoticedMeetingIdList() { | |||
// Object result = redisUtils.get(MEETING_INVITE_COMPLETE_NOTICED_MEETING_ID_CACHE_KEY); | |||
// HashSet<Long> completeNoticedMeetingIdSet = new HashSet<>(); | |||
// if (Objects.nonNull(result)) { | |||
// String resultStr = result.toString(); | |||
// List<Long> completeNoticedMeetingIdList = JSONObject.parseArray(resultStr, Long.class); | |||
// completeNoticedMeetingIdSet = new HashSet<>(completeNoticedMeetingIdList); | |||
// } | |||
// return completeNoticedMeetingIdSet; | |||
// } | |||
// | |||
//} |
@@ -1,160 +0,0 @@ | |||
//package com.ningdatech.pmapi.meeting.task; | |||
// | |||
//import cn.hutool.crypto.SecureUtil; | |||
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
//import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
//import com.ningdatech.basic.util.CollUtils; | |||
//import com.ningdatech.basic.util.StrPool; | |||
//import com.ningdatech.cache.model.cache.CacheHashKey; | |||
//import com.ningdatech.cache.repository.CachePlusOps; | |||
//import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService; | |||
//import com.ningdatech.pmapi.meeting.entity.domain.Meeting; | |||
//import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpert; | |||
//import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatus; | |||
//import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; | |||
//import com.ningdatech.pmapi.meeting.service.IMeetingExpertService; | |||
//import com.ningdatech.pmapi.meeting.service.IMeetingService; | |||
//import com.ningdatech.pmapi.meta.helper.DictionaryCache; | |||
//import lombok.AllArgsConstructor; | |||
//import lombok.Data; | |||
//import lombok.extern.slf4j.Slf4j; | |||
//import org.springframework.scheduling.annotation.Scheduled; | |||
//import org.springframework.stereotype.Component; | |||
// | |||
//import java.time.LocalDateTime; | |||
//import java.time.temporal.ChronoUnit; | |||
//import java.util.ArrayList; | |||
//import java.util.HashMap; | |||
//import java.util.List; | |||
//import java.util.Map; | |||
//import java.util.stream.Collectors; | |||
// | |||
///** | |||
// * <p> | |||
// * NoticeExpertAt24HoursBeforeMeetingTask | |||
// * </p> | |||
// * | |||
// * @author WendyYang | |||
// * @since 09:16 2022/11/16 | |||
// */ | |||
//@Slf4j | |||
//@Component | |||
//@AllArgsConstructor | |||
//public class NoticeExpertAt24HoursBeforeMeetingTask { | |||
// | |||
// @Data | |||
// private static class NoticeValue { | |||
// | |||
// private LocalDateTime startTime; | |||
// | |||
// private String addressMd5; | |||
// | |||
// } | |||
// | |||
// private final IMeetingService meetingService; | |||
// private final IMeetingExpertService meetingExpertService; | |||
// private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | |||
// private final DictionaryCache dictionaryCache; | |||
// private final CachePlusOps cachePlusOps; | |||
// private final IExpertUserFullInfoService expertUserFullInfoService; | |||
// | |||
// private static final String EXPERT_NOTICE_AT_24H_BEFORE_MEETING = "EXPERT_NOTICE_AT_24H_BEFORE_MEETING"; | |||
// | |||
// private void addNoticeKey(Long meetingId, Map<String, Object> noticeValue, LocalDateTime startTime) { | |||
// long mills = ChronoUnit.SECONDS.between(LocalDateTime.now(), startTime); | |||
// CacheHashKey key = new CacheHashKey(); | |||
// key.setKey(EXPERT_NOTICE_AT_24H_BEFORE_MEETING + StrPool.COLON + meetingId); | |||
// key.setField(mills); | |||
// cachePlusOps.hSet(key, noticeValue); | |||
// } | |||
// | |||
// private Map<Long, NoticeValue> getNoticeKey(Long meetingId) { | |||
// Map<Object, Object> cache = cachePlusOps.hGet(EXPERT_NOTICE_AT_24H_BEFORE_MEETING + StrPool.COLON + meetingId); | |||
// return cache.entrySet().stream().collect(Collectors.toMap(w -> Long.valueOf(w.getKey().toString()), w -> (NoticeValue) w.getValue())); | |||
// } | |||
// | |||
// /** | |||
// * 查询需要发送通知的会议: | |||
// * <ul>1. 未完成</ul> | |||
// * <ul>2. 创建邀请</ul> | |||
// * <ul>3. 当前时间距离会议开始时间不足24小时</ul> | |||
// * | |||
// * @return 会议信息 | |||
// * @author WendyYang | |||
// **/ | |||
// private Map<Long, Meeting> loadMeetingAt24HoursBeforeMeeting() { | |||
// LambdaQueryWrapper<Meeting> query = Wrappers.lambdaQuery(Meeting.class); | |||
// LocalDateTime now = LocalDateTime.now(), hoursAgoBy24 = now.plusHours(24); | |||
// // 10分钟之内不再发送通知 | |||
// query.between(Meeting::getStartTime, now.plusMinutes(10), hoursAgoBy24); | |||
// query.eq(Meeting::getStatus, MeetingStatus.Manager.UNCOMPLETED.getCode()); | |||
// query.eq(Meeting::getInvited, Boolean.TRUE); | |||
// List<Meeting> meetings = meetingService.list(query); | |||
// return CollUtils.listToMap(meetings, Meeting::getId); | |||
// } | |||
// | |||
// private String addressDetailMd5(Meeting meeting) { | |||
// String content = meeting.getRegionCode() + StrPool.HASH + meeting.getRegionLevel() + StrPool.HASH + meeting.getRegionDetail(); | |||
// return SecureUtil.md5(content); | |||
// } | |||
// | |||
// private boolean skipExpert(NoticeValue noticeValue, String addressMd5, LocalDateTime startTime) { | |||
// boolean skip = noticeValue.getAddressMd5().equals(addressMd5); | |||
// if (skip) { | |||
// skip = noticeValue.getStartTime().equals(startTime); | |||
// } | |||
// return skip; | |||
// } | |||
// | |||
// @Scheduled(cron = "${expert-attend-notice.cron:0 0/5 7-21 * * ?}") | |||
// public void execute() { | |||
// log.info("开始执行会议开始前24小时再次短信提醒任务"); | |||
// Map<Long, Meeting> meetingsMap = loadMeetingAt24HoursBeforeMeeting(); | |||
// if (meetingsMap.isEmpty()) { | |||
// return; | |||
// } | |||
// List<MeetingExpert> expertList = meetingExpertService.listExpertByAgreeAttend(meetingsMap.keySet()); | |||
// if (expertList.isEmpty()) { | |||
// return; | |||
// } | |||
// List<SendSmsCmd.SendSmsContext> contexts = new ArrayList<>(); | |||
// Map<Long, List<MeetingExpert>> expertGroup = CollUtils.group(expertList, MeetingExpert::getMeetingId); | |||
// expertGroup.forEach((meetingId, experts) -> { | |||
// Map<String, Object> noticeCache = new HashMap<>(16); | |||
// Meeting meeting = meetingsMap.get(meetingId); | |||
// String md5 = addressDetailMd5(meeting); | |||
// Map<Long, NoticeValue> noticeKey = getNoticeKey(meetingId); | |||
// String holdCompany = meeting.getHoldCompanyBracket(); | |||
// String startTime = meeting.getStartTime().format(DateUtil.DTF_YMD_HM); | |||
// String meetingType = dictionaryCache.getByCode(meeting.getType()).getName(); | |||
// for (MeetingExpert expert : experts) { | |||
// NoticeValue noticeValue = noticeKey.get(expert.getId()); | |||
// if (noticeValue != null) { | |||
// if (skipExpert(noticeValue, md5, meeting.getStartTime())) { | |||
// continue; | |||
// } | |||
// } | |||
// NoticeValue value = new NoticeValue(); | |||
// value.setAddressMd5(md5); | |||
// value.setStartTime(meeting.getStartTime()); | |||
// noticeCache.put(expert.getId().toString(), value); | |||
// SendSmsCmd.SendSmsContext context = new SendSmsCmd.SendSmsContext(); | |||
// | |||
// ExpertUserFullInfo expertUserFullInfo = expertUserFullInfoService.getByUserId(expert.getExpertId()); | |||
// String content = String.format(YxtSmsTemplateConst.SEND_MEETING_NOTICE, expertUserFullInfo.getName(), | |||
// expert.getUpdateOn().format(DateUtil.DTF_YMD_HM), meetingType, startTime, | |||
// meeting.getRegionDetail(), meeting.getContact()); | |||
// context.setContent(holdCompany + content); | |||
// context.setReceiveNumber(expert.getMobile()); | |||
// contexts.add(context); | |||
// } | |||
// if (!noticeCache.isEmpty()) { | |||
// addNoticeKey(meetingId, noticeCache, meeting.getStartTime()); | |||
// } | |||
// }); | |||
// if (!contexts.isEmpty()) { | |||
// yxtCallOrSmsHelper.sendSms(contexts); | |||
// } | |||
// } | |||
// | |||
//} |