@@ -3,6 +3,7 @@ package com.hz.pm.api.external; | |||
import cn.hutool.core.date.LocalDateTimeUtil; | |||
import cn.hutool.core.io.resource.ClassPathResource; | |||
import cn.hutool.core.lang.TypeReference; | |||
import cn.hutool.core.util.StrUtil; | |||
import cn.hutool.http.HttpUtil; | |||
import cn.hutool.json.JSONObject; | |||
import cn.hutool.json.JSONUtil; | |||
@@ -10,7 +11,7 @@ import com.hz.pm.api.common.util.EnvironmentUtil; | |||
import com.hz.pm.api.external.model.dto.*; | |||
import com.hz.pm.api.external.model.enumeration.MhDictType; | |||
import com.hz.pm.api.meeting.entity.req.MeetingIdReq; | |||
import com.hz.pm.api.open.model.vo.MeetingExpertInfoVO; | |||
import com.hz.pm.api.open.model.vo.MeetingExpertToMhDTO; | |||
import com.ningdatech.basic.exception.BizException; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
@@ -193,19 +194,22 @@ public class MhApiClient { | |||
throw BizException.wrap("获取测评报告失败"); | |||
} | |||
public void pushMeetingAndExpertsDataToMh(MeetingExpertInfoVO data) { | |||
public String pushMeetingAndExpertsDataToMh(MeetingExpertToMhDTO data) { | |||
if (environmentUtil.isDevEnv()) { | |||
return; | |||
return StrUtil.EMPTY; | |||
} | |||
String requestUrl = mhApiHost + PUSH_MEETING_EXPERTS_DATA; | |||
log.info("推送会议专家信息到MH:{}", data); | |||
String retBody = HttpUtil.post(requestUrl, JSONUtil.toJsonStr(data)); | |||
MhRetDTO<Object> retObj = JSONUtil.toBean(retBody, | |||
new TypeReference<MhRetDTO<Object>>() { | |||
MhRetDTO<JSONObject> retObj = JSONUtil.toBean(retBody, | |||
new TypeReference<MhRetDTO<JSONObject>>() { | |||
}, false); | |||
if (!retObj.isOk()) { | |||
log.error("会议专家信息推送失败:{}", retBody); | |||
return StrUtil.EMPTY; | |||
} | |||
// 返回信产会议签到页面地址 | |||
return retObj.getData().getStr("url"); | |||
} | |||
public void cancelMeetingToMh(Long meetingId) { | |||
@@ -113,7 +113,7 @@ public class LeaveManage { | |||
LocalDateTime endTime = leaveTimes.get(leaveTimes.size() - 1).getValue(); | |||
LambdaQueryWrapper<Meeting> meetingQuery = Wrappers.lambdaQuery(Meeting.class) | |||
.in(Meeting::getId, meetingIds) | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode()) | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCEL.getCode()) | |||
.and(w -> w.between(Meeting::getStartTime, startTime, endTime) | |||
.or(or -> or.between(Meeting::getEndTime, startTime, endTime))); | |||
List<Meeting> meetingList = meetingService.list(meetingQuery); | |||
@@ -172,7 +172,7 @@ public class LeaveManage { | |||
private void leaveProcessByTemporary(LeaveCreateReq po, Long leaveUserId, ExpertLeave leave, List<KeyValDTO<LocalDateTime, LocalDateTime>> leaveDetailTimes) { | |||
// 临时请假 | |||
Meeting meeting = meetingService.getById(po.getMeetingId()); | |||
if (MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||
if (MeetingStatusEnum.CANCEL.eq(meeting.getStatus())) { | |||
throw BizException.wrap("该会议已取消"); | |||
} | |||
po.setStartTime(meeting.getStartTime()); | |||
@@ -1,6 +1,7 @@ | |||
package com.hz.pm.api.meeting.entity.domain; | |||
import com.baomidou.mybatisplus.annotation.*; | |||
import com.hz.pm.api.meeting.entity.enumeration.MeetingStatusEnum; | |||
import io.swagger.annotations.ApiModel; | |||
import io.swagger.annotations.ApiModelProperty; | |||
import lombok.Data; | |||
@@ -51,6 +52,16 @@ public class Meeting implements Serializable { | |||
@ApiModelProperty("会议地址") | |||
private String meetingAddress; | |||
@ApiModelProperty("评审地点经度") | |||
private Double addressLongitude; | |||
@ApiModelProperty("评审地点纬度") | |||
private Double addressLatitude; | |||
/** | |||
* @see MeetingStatusEnum | |||
*/ | |||
@ApiModelProperty("会议状态") | |||
private Integer status; | |||
@ApiModelProperty("抽取状态") | |||
@@ -59,6 +70,9 @@ public class Meeting implements Serializable { | |||
@ApiModelProperty("是否确认名单") | |||
private Boolean confirmedRoster; | |||
@ApiModelProperty("签到二维码地址") | |||
private String signQrCodeUrl; | |||
@ApiModelProperty("举办单位") | |||
private String holdOrg; | |||
@@ -53,6 +53,12 @@ public class MeetingBasicDTO { | |||
@ApiModelProperty("评审地点") | |||
private String meetingAddress; | |||
@ApiModelProperty("评审地点经度") | |||
private Double addressLongitude; | |||
@ApiModelProperty("评审地点纬度") | |||
private Double addressLatitude; | |||
@NotBlank(message = "短信通知签名不能为空") | |||
@Length(min = 1, max = 20, message = "短信通知签名无效") | |||
@ApiModelProperty("短信通知签名") | |||
@@ -4,6 +4,7 @@ import lombok.AllArgsConstructor; | |||
import lombok.Getter; | |||
import java.util.Arrays; | |||
import java.util.Optional; | |||
/** | |||
* <p> | |||
@@ -21,7 +22,7 @@ public enum MeetingStatusEnum { | |||
* 会议状态 | |||
*/ | |||
NORMAL("正常", 1), | |||
CANCELED("已取消", 3); | |||
CANCEL("已取消", 3); | |||
private final String value; | |||
private final Integer code; | |||
@@ -30,11 +31,14 @@ public enum MeetingStatusEnum { | |||
return this.getCode().equals(code); | |||
} | |||
public static MeetingStatusEnum getByCode(Integer code) { | |||
public static Optional<MeetingStatusEnum> getByCode(Integer code) { | |||
return Arrays.stream(values()) | |||
.filter(w -> w.getCode().equals(code)) | |||
.findFirst() | |||
.orElseThrow(() -> new IllegalArgumentException("会议状态编码无效")); | |||
.findFirst(); | |||
} | |||
public static MeetingStatusEnum getNoNull(Integer code) { | |||
return getByCode(code).orElseThrow(() -> new IllegalArgumentException("会议状态无效")); | |||
} | |||
} |
@@ -99,4 +99,7 @@ public class MeetingByManagerVO { | |||
@ApiModelProperty("专家签到地点") | |||
private String signAddress; | |||
@ApiModelProperty("签到二维码") | |||
private String signQrCodeUrl; | |||
} |
@@ -114,6 +114,7 @@ public class MeetingManageHelper { | |||
result.setMeetingAddress(meeting.getMeetingAddress()); | |||
result.setIsInnerProject(meeting.getIsInnerProject()); | |||
result.setHasMeetingResult(StrUtil.isNotBlank(meeting.getResultDescription())); | |||
result.setSignQrCodeUrl(meeting.getSignQrCodeUrl()); | |||
return result; | |||
} | |||
@@ -545,7 +545,7 @@ public class ExpertInviteManage { | |||
LambdaQueryWrapper<Meeting> query = Wrappers.lambdaQuery(Meeting.class) | |||
.select(Meeting::getId) | |||
.eq(Meeting::getInviteStatus, Boolean.TRUE) | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode()) | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCEL.getCode()) | |||
.orderByDesc(Meeting::getCreateOn) | |||
.last("limit " + recentMeetingCount); | |||
List<Long> meetingIds = CollUtils.fieldList(meetingService.list(query), Meeting::getId); | |||
@@ -61,7 +61,7 @@ public class MeetingExpertJudgeManage { | |||
} | |||
// 会议状态校验 | |||
Meeting meeting = meetingService.getById(req.getMeetingId()); | |||
if (meeting == null || MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||
if (meeting == null || MeetingStatusEnum.CANCEL.eq(meeting.getStatus())) { | |||
throw BizException.wrap("会议不存在或已取消"); | |||
} | |||
// 专家抽取状态校验 | |||
@@ -40,7 +40,7 @@ import com.hz.pm.api.meeting.task.ExpertRandomInviteTask; | |||
import com.hz.pm.api.meta.helper.DictionaryCache; | |||
import com.hz.pm.api.meta.helper.TagCache; | |||
import com.hz.pm.api.open.model.vo.ExpertInfoVO; | |||
import com.hz.pm.api.open.model.vo.MeetingExpertInfoVO; | |||
import com.hz.pm.api.open.model.vo.MeetingExpertToMhDTO; | |||
import com.hz.pm.api.organization.service.IDingOrganizationService; | |||
import com.hz.pm.api.projectlib.model.entity.Project; | |||
import com.hz.pm.api.projectlib.model.enumeration.status.ProjectStatus; | |||
@@ -137,7 +137,7 @@ public class MeetingManage { | |||
// 保存会议基本信息 | |||
Meeting meeting = BeanUtil.copyProperties(meetingBasic, Meeting.class); | |||
meeting.setStatus(MeetingStatusEnum.NORMAL.getCode()); | |||
meeting.setHoldOrg(String.valueOf(userDetail.getMhUnitName())); | |||
meeting.setHoldOrg(userDetail.getMhUnitName()); | |||
meeting.setHoldOrgCode(String.valueOf(userDetail.getMhUnitId())); | |||
meeting.setCreator(userDetail.getUsername()); | |||
meeting.setInviteStatus(Boolean.FALSE); | |||
@@ -337,7 +337,7 @@ public class MeetingManage { | |||
.orderByDesc(Meeting::getCreateOn) | |||
.in(Meeting::getId, mapByMeetingId.keySet()) | |||
.eq(Meeting::getConfirmedRoster, Boolean.TRUE) | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode()); | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCEL.getCode()); | |||
if (req.getExpertId() == null) { | |||
meetingManageHelper.buildMeetingQuery(query, req); | |||
} | |||
@@ -381,7 +381,7 @@ public class MeetingManage { | |||
.orderByAsc(Meeting::getStartTime) | |||
.in(Meeting::getId, meetingMap.keySet()) | |||
.eq(Meeting::getConfirmedRoster, Boolean.TRUE) | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode()); | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCEL.getCode()); | |||
Page<Meeting> page = meetingService.page(req.page(), query); | |||
if (page.getTotal() == 0) { | |||
return PageVo.empty(); | |||
@@ -688,14 +688,14 @@ public class MeetingManage { | |||
} | |||
try { | |||
Meeting meeting = meetingService.getById(meetingId); | |||
if (MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||
if (MeetingStatusEnum.CANCEL.eq(meeting.getStatus())) { | |||
throw ReturnException.wrap("会议已取消"); | |||
} | |||
if (meeting.getStartTime().isBefore(LocalDateTime.now())) { | |||
throw ReturnException.wrap("会议已开始,暂时无法取消"); | |||
} | |||
Wrapper<Meeting> meetingUpdate = Wrappers.lambdaUpdate(Meeting.class) | |||
.set(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode()) | |||
.set(Meeting::getStatus, MeetingStatusEnum.CANCEL.getCode()) | |||
.eq(Meeting::getId, meetingId); | |||
meetingService.update(meetingUpdate); | |||
// 取消抽取任务 | |||
@@ -763,7 +763,7 @@ public class MeetingManage { | |||
} | |||
try { | |||
Meeting meeting = meetingService.getById(req.getMeetingId()); | |||
if (MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||
if (MeetingStatusEnum.CANCEL.eq(meeting.getStatus())) { | |||
throw BizException.wrap("会议已取消!"); | |||
} | |||
if (LocalDateTime.now().isAfter(meeting.getStartTime())) { | |||
@@ -793,7 +793,7 @@ public class MeetingManage { | |||
} | |||
try { | |||
Meeting meeting = meetingService.getById(req.getMeetingId()); | |||
if (MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||
if (MeetingStatusEnum.CANCEL.eq(meeting.getStatus())) { | |||
throw BizException.wrap("会议已取消"); | |||
} | |||
Wrapper<MeetingExpert> update = Wrappers.lambdaUpdate(MeetingExpert.class) | |||
@@ -813,7 +813,7 @@ public class MeetingManage { | |||
} | |||
try { | |||
Meeting meeting = meetingService.getById(req.getMeetingId()); | |||
if (MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||
if (MeetingStatusEnum.CANCEL.eq(meeting.getStatus())) { | |||
throw BizException.wrap("会议已取消"); | |||
} | |||
Wrapper<MeetingExpert> cancel = Wrappers.lambdaUpdate(MeetingExpert.class) | |||
@@ -849,14 +849,15 @@ public class MeetingManage { | |||
} | |||
List<MeetingExpert> experts = meetingExpertService.listAgreedExperts(meetingId); | |||
if (Boolean.FALSE.equals(meeting.getConfirmedRoster())) { | |||
// 将已确认专家名单的当前会议信息和专家数据同步到信创 | |||
MeetingExpertToMhDTO data = buildMeetingExpertSyncToMhData(meeting, experts); | |||
String signQrCodeUrl = mhApiClient.pushMeetingAndExpertsDataToMh(data); | |||
// 首次确认的 | |||
Wrapper<Meeting> update = Wrappers.lambdaUpdate(Meeting.class) | |||
.set(Meeting::getConfirmedRoster, Boolean.TRUE) | |||
.set(Meeting::getSignQrCodeUrl, signQrCodeUrl) | |||
.eq(Meeting::getId, meetingId); | |||
meetingService.update(update); | |||
// 将已确认专家名单的当前会议信息和专家数据同步到信创 | |||
MeetingExpertInfoVO data = getMeetingExpertInfoVO(meeting, experts); | |||
mhApiClient.pushMeetingAndExpertsDataToMh(data); | |||
} | |||
List<MeetingExpert> expertNoticing = experts.stream() | |||
.filter(w -> meeting.getConfirmedRoster() || !w.getConfirmedRoster()) | |||
@@ -878,8 +879,8 @@ public class MeetingManage { | |||
} | |||
private MeetingExpertInfoVO getMeetingExpertInfoVO(Meeting meeting, List<MeetingExpert> experts) { | |||
MeetingExpertInfoVO data = new MeetingExpertInfoVO(); | |||
private MeetingExpertToMhDTO buildMeetingExpertSyncToMhData(Meeting meeting, List<MeetingExpert> experts) { | |||
MeetingExpertToMhDTO data = new MeetingExpertToMhDTO(); | |||
data.setMeetingId(meeting.getId()); | |||
data.setStartTime(meeting.getStartTime()); | |||
data.setEndTime(meeting.getEndTime()); | |||
@@ -887,6 +888,8 @@ public class MeetingManage { | |||
data.setMeetingAddress(meeting.getMeetingAddress()); | |||
data.setConnecter(meeting.getConnecter()); | |||
data.setContact(meeting.getContact()); | |||
data.setLongitude(meeting.getAddressLongitude()); | |||
data.setLatitude(meeting.getAddressLatitude()); | |||
// 获取未签到的专家信息 | |||
Set<Long> expertIds = experts.stream() | |||
.filter(m -> Boolean.FALSE.equals(m.getSignStatus())) | |||
@@ -1005,7 +1008,7 @@ public class MeetingManage { | |||
} | |||
try { | |||
Meeting meeting = meetingService.getById(req.getMeetingId()); | |||
if (meeting == null || MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||
if (meeting == null || MeetingStatusEnum.CANCEL.eq(meeting.getStatus())) { | |||
throw BizException.wrap("会议不存在或已取消"); | |||
} | |||
LocalDateTime now = LocalDateTime.now(); | |||
@@ -1041,7 +1044,7 @@ public class MeetingManage { | |||
} | |||
try { | |||
Meeting meeting = meetingService.getById(req.getMeetingId()); | |||
if (meeting == null || MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||
if (meeting == null || MeetingStatusEnum.CANCEL.eq(meeting.getStatus())) { | |||
throw BizException.wrap("会议不存在或已取消"); | |||
} | |||
LocalDateTime now = LocalDateTime.now(); | |||
@@ -14,8 +14,7 @@ import org.springframework.web.bind.annotation.RestController; | |||
import com.hz.pm.api.open.manage.OpenApiMeetingExpertInfoManage; | |||
import com.hz.pm.api.open.model.po.ReqMeetingExpertInfoPO; | |||
import com.hz.pm.api.open.model.vo.MeetingExpertInfoVO; | |||
import com.ningdatech.log.annotation.WebLog; | |||
import com.hz.pm.api.open.model.vo.MeetingExpertToMhDTO; | |||
import io.swagger.annotations.ApiOperation; | |||
import lombok.RequiredArgsConstructor; | |||
@@ -39,7 +38,7 @@ public class OpenApiMeetingExpertInfoController { | |||
@PostMapping("/list") | |||
@ApiOperation("获取已抽取完成会议确定参加会议且未签到的专家信息列表") | |||
public List<MeetingExpertInfoVO> infoList(@Valid @RequestBody ReqMeetingExpertInfoPO po) { | |||
public List<MeetingExpertToMhDTO> infoList(@Valid @RequestBody ReqMeetingExpertInfoPO po) { | |||
return openMeetingExpertInfoManage.infoList(po); | |||
} | |||
@@ -11,14 +11,11 @@ import com.hz.pm.api.expert.entity.ExpertUserFullInfo; | |||
import com.hz.pm.api.expert.model.dto.DictionaryVO; | |||
import com.hz.pm.api.expert.service.IExpertUserFullInfoService; | |||
import com.hz.pm.api.meeting.entity.enumeration.ExpertAttendStatusEnum; | |||
import com.hz.pm.api.meeting.entity.enumeration.ExpertInviteTypeEnum; | |||
import com.hz.pm.api.meeting.entity.enumeration.MeetingStatusByDashboard; | |||
import com.hz.pm.api.meeting.entity.enumeration.MeetingStatusEnum; | |||
import com.hz.pm.api.meta.model.dto.DictionaryDTO; | |||
import com.hz.pm.api.open.model.po.ReqMeetingExpertSignPO; | |||
import com.hz.pm.api.user.model.entity.UserInfo; | |||
import com.hz.pm.api.user.security.model.UserFullInfoDTO; | |||
import com.ningdatech.basic.function.VUtils; | |||
import org.springframework.beans.factory.annotation.Value; | |||
import org.springframework.stereotype.Component; | |||
@@ -36,7 +33,7 @@ import com.hz.pm.api.meta.model.entity.ExpertDictionary; | |||
import com.hz.pm.api.meta.service.IExpertDictionaryService; | |||
import com.hz.pm.api.open.model.po.ReqMeetingExpertInfoPO; | |||
import com.hz.pm.api.open.model.vo.ExpertInfoVO; | |||
import com.hz.pm.api.open.model.vo.MeetingExpertInfoVO; | |||
import com.hz.pm.api.open.model.vo.MeetingExpertToMhDTO; | |||
import com.hz.pm.api.user.service.IUserInfoService; | |||
import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.basic.util.CollUtils; | |||
@@ -64,7 +61,7 @@ public class OpenApiMeetingExpertInfoManage { | |||
private final IExpertDictionaryService iExpertDictionaryService; | |||
private final DictionaryCache dictionaryCache; | |||
private final IExpertUserFullInfoService expertUserFullInfoService; | |||
public List<MeetingExpertInfoVO> infoList(ReqMeetingExpertInfoPO po) { | |||
public List<MeetingExpertToMhDTO> infoList(ReqMeetingExpertInfoPO po) { | |||
String key = po.getKey(); | |||
// 校验传入的签名 | |||
if (!checkSign(key)){ | |||
@@ -73,11 +70,11 @@ public class OpenApiMeetingExpertInfoManage { | |||
// 获取已经抽取(指定)完成 确认参加会议并且未签到的专家信息 | |||
List<Meeting> meetingList = meetingService.list(Wrappers.lambdaQuery(Meeting.class) | |||
.eq(Meeting::getConfirmedRoster, Boolean.TRUE) | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode())); | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCEL.getCode())); | |||
if(CollUtil.isEmpty(meetingList)){ | |||
return Collections.emptyList(); | |||
} | |||
List<MeetingExpertInfoVO> result = Lists.newArrayList(); | |||
List<MeetingExpertToMhDTO> result = Lists.newArrayList(); | |||
// 获取已抽取完成会议中同意参加但未签到的专家信息 | |||
List<Long> meetingIds = meetingList.stream().map(Meeting::getId).collect(Collectors.toList()); | |||
Map<Long, List<MeetingExpert>> meetingExpertMap = meetingExpertService.list(Wrappers.lambdaQuery(MeetingExpert.class) | |||
@@ -116,7 +113,7 @@ public class OpenApiMeetingExpertInfoManage { | |||
Map<Long, List<ExpertDictionary>> dictMap = expertDictionaryList.stream().collect(Collectors.groupingBy(ExpertDictionary::getUserId)); | |||
for (Map.Entry<Long, List<MeetingExpert>> entry : meetingExpertMap.entrySet()) { | |||
MeetingExpertInfoVO vo = new MeetingExpertInfoVO(); | |||
MeetingExpertToMhDTO vo = new MeetingExpertToMhDTO(); | |||
Long meetingId = entry.getKey(); | |||
Meeting meeting = meetingMap.get(meetingId); | |||
if (Objects.nonNull(meeting)){ | |||
@@ -13,8 +13,7 @@ import lombok.Data; | |||
* @since 2024/05/10 17:16 | |||
*/ | |||
@Data | |||
public class MeetingExpertInfoVO { | |||
public class MeetingExpertToMhDTO { | |||
/** | |||
* 会议信息 | |||
@@ -35,6 +34,12 @@ public class MeetingExpertInfoVO { | |||
@ApiModelProperty("会议地址") | |||
private String meetingAddress; | |||
@ApiModelProperty("会议地址经度") | |||
private Double longitude; | |||
@ApiModelProperty("会议地址纬度") | |||
private Double latitude; | |||
@ApiModelProperty("联系人") | |||
private String connecter; | |||