@@ -1,6 +1,10 @@ | |||||
package com.ningdatech.pmapi.meeting.controller; | package com.ningdatech.pmapi.meeting.controller; | ||||
import cn.hutool.core.io.FileUtil; | |||||
import cn.hutool.json.JSON; | |||||
import cn.hutool.json.JSONObject; | |||||
import cn.hutool.json.JSONUtil; | |||||
import com.ningdatech.basic.model.IdVo; | import com.ningdatech.basic.model.IdVo; | ||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
import com.ningdatech.log.annotation.WebLog; | import com.ningdatech.log.annotation.WebLog; | ||||
@@ -14,6 +18,9 @@ import org.springframework.validation.annotation.Validated; | |||||
import org.springframework.web.bind.annotation.*; | import org.springframework.web.bind.annotation.*; | ||||
import javax.validation.Valid; | import javax.validation.Valid; | ||||
import java.util.List; | |||||
import java.util.Set; | |||||
import java.util.stream.Collectors; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
@@ -67,17 +74,17 @@ public class MeetingController { | |||||
} | } | ||||
@ApiOperation("会议详情-基本信息") | @ApiOperation("会议详情-基本信息") | ||||
@GetMapping("detail/{meetingId}/basicInfo") | |||||
@GetMapping("/basicInfo/{meetingId}") | |||||
@WebLog(value = "会议详情-基本信息") | @WebLog(value = "会议详情-基本信息") | ||||
public MeetingDetailBasicVO meetingBasic(@PathVariable Long meetingId) { | public MeetingDetailBasicVO meetingBasic(@PathVariable Long meetingId) { | ||||
return meetingManage.getMeetingDetail(meetingId); | return meetingManage.getMeetingDetail(meetingId); | ||||
} | } | ||||
@ApiOperation("邀请情况详情") | |||||
@GetMapping("/detail/{meetingId}/inviteDetail") | |||||
@ApiOperation("抽取情况") | |||||
@GetMapping("/inviteExpertList/{meetingId}") | |||||
@WebLog(value = "邀请情况详请") | @WebLog(value = "邀请情况详请") | ||||
public ExpertInviteDetailVO inviteDetail(@PathVariable Long meetingId) { | |||||
return meetingManage.inviteDetail(meetingId); | |||||
public ExpertInviteDetailVO inviteExpertList(@PathVariable Long meetingId) { | |||||
return meetingManage.inviteExpertList(meetingId); | |||||
} | } | ||||
@ApiOperation("会议基础信息修改") | @ApiOperation("会议基础信息修改") | ||||
@@ -88,33 +95,17 @@ public class MeetingController { | |||||
} | } | ||||
@ApiOperation("会议详情-抽取规则") | @ApiOperation("会议详情-抽取规则") | ||||
@GetMapping("/detail/inviteRule/{meetingId}") | |||||
@GetMapping("/inviteRuleDetail/{meetingId}") | |||||
@WebLog(value = "会议详情-抽取规则") | @WebLog(value = "会议详情-抽取规则") | ||||
public InviteRuleDetailVO inviteRuleDetail(@PathVariable Long meetingId) { | public InviteRuleDetailVO inviteRuleDetail(@PathVariable Long meetingId) { | ||||
return meetingManage.inviteRuleDetail(meetingId); | return meetingManage.inviteRuleDetail(meetingId); | ||||
} | } | ||||
@ApiOperation("专家移除") | |||||
@PostMapping("/expertRemove") | |||||
@WebLog(value = "专家移除") | |||||
public void expertRemove(@RequestBody ExpertRemoveReq po) { | |||||
meetingManage.expertRemove(po); | |||||
} | |||||
@ApiOperation("专家替换") | @ApiOperation("专家替换") | ||||
@PostMapping("/expertReplace") | @PostMapping("/expertReplace") | ||||
@WebLog(value = "专家替换") | @WebLog(value = "专家替换") | ||||
public void expertReplace(@RequestBody ExpertRemoveReq po) { | public void expertReplace(@RequestBody ExpertRemoveReq po) { | ||||
meetingManage.expertReplace(po); | meetingManage.expertReplace(po); | ||||
} | |||||
@ApiOperation("确认名单(下发会议通知)") | |||||
@GetMapping("/sendMeetingNotice/{meetingId}") | |||||
@WebLog(value = "确认名单(下发会议通知") | |||||
public void sendMeetingNotice(@PathVariable Long meetingId) { | |||||
meetingManage.sendMeetingNotice(meetingId); | |||||
} | } | ||||
@ApiOperation("停止抽取") | @ApiOperation("停止抽取") | ||||
@@ -122,7 +113,6 @@ public class MeetingController { | |||||
@WebLog(value = "停止抽取") | @WebLog(value = "停止抽取") | ||||
public void stopInvite(@PathVariable Long meetingId) { | public void stopInvite(@PathVariable Long meetingId) { | ||||
meetingManage.stopRandomInvite(meetingId); | meetingManage.stopRandomInvite(meetingId); | ||||
} | } | ||||
@ApiOperation("取消会议") | @ApiOperation("取消会议") | ||||
@@ -133,10 +123,10 @@ public class MeetingController { | |||||
} | } | ||||
@ApiOperation("邀请函信息") | @ApiOperation("邀请函信息") | ||||
@GetMapping("/expertInvitationDetail") | |||||
@GetMapping("/expertInviteDetail") | |||||
@WebLog(value = "邀请函信息") | @WebLog(value = "邀请函信息") | ||||
public ExpertInvitationDetailVO expertInvitationDetail(@RequestParam("meetingId") Long meetingId, | |||||
@RequestParam(required = false) Long expertId) { | |||||
public ExpertInvitationDetailVO expertInvitationDetail(@RequestParam(required = false) Long expertId, | |||||
@RequestParam Long meetingId) { | |||||
return meetingManage.expertInvitationDetail(meetingId, expertId); | return meetingManage.expertInvitationDetail(meetingId, expertId); | ||||
} | } | ||||
@@ -148,10 +138,33 @@ public class MeetingController { | |||||
} | } | ||||
@ApiOperation("确认参加") | @ApiOperation("确认参加") | ||||
@PostMapping("/confirmAttendByManager") | |||||
@PostMapping("/expert/confirm") | |||||
@WebLog(value = "确认参加") | @WebLog(value = "确认参加") | ||||
public void confirmAttendByManager(@RequestBody ExpertRemoveReq po) { | |||||
meetingManage.confirmAttendByManager(po); | |||||
public void confirmAttendByManager(@RequestBody ExpertConfirmReq req) { | |||||
meetingManage.confirmAttendByManager(req); | |||||
} | } | ||||
@ApiOperation("释放专家") | |||||
@PostMapping("/expert/release") | |||||
@WebLog(value = "释放专家") | |||||
public void releaseExperts(@RequestBody MeetingCancelReq req) { | |||||
meetingManage.releaseExperts(req); | |||||
} | |||||
@ApiOperation("设置专家组长") | |||||
@PostMapping("setUpHeadman") | |||||
@WebLog(value = "设置专家组长") | |||||
public void setUpHeadman(@RequestBody ExpertConfirmReq req){ | |||||
meetingManage.setUpHeadman(req); | |||||
} | |||||
@ApiOperation("重发短信") | |||||
@PostMapping("/confirmedRoster") | |||||
@WebLog(value = "重发短信") | |||||
public void resendSms(MeetingCancelReq req){ | |||||
meetingManage.confirmedRoster(req.getMeetingId()); | |||||
} | |||||
} | } |
@@ -1,20 +0,0 @@ | |||||
package com.ningdatech.pmapi.meeting.controller; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.stereotype.Controller; | |||||
/** | |||||
* <p> | |||||
* 会议评审内部项目表 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023-02-28 | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/pmapi.meeting/meeting-inner-project") | |||||
public class MeetingInnerProjectController { | |||||
} |
@@ -1,20 +0,0 @@ | |||||
package com.ningdatech.pmapi.meeting.controller; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.stereotype.Controller; | |||||
/** | |||||
* <p> | |||||
* 会议评审外部项目 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023-02-28 | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/pmapi.meeting/meeting-outer-project") | |||||
public class MeetingOuterProjectController { | |||||
} |
@@ -54,22 +54,6 @@ public class Meeting implements Serializable { | |||||
@ApiModelProperty("联系方式") | @ApiModelProperty("联系方式") | ||||
private String contact; | private String contact; | ||||
@ApiModelProperty("创建人ID") | |||||
@TableField(fill = FieldFill.INSERT) | |||||
private Long createBy; | |||||
@ApiModelProperty("创建时间") | |||||
@TableField(fill = FieldFill.INSERT) | |||||
private LocalDateTime createOn; | |||||
@ApiModelProperty("修改人ID") | |||||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||||
private Long updateBy; | |||||
@ApiModelProperty("修改时间") | |||||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||||
private LocalDateTime updateOn; | |||||
@ApiModelProperty("创建人") | @ApiModelProperty("创建人") | ||||
private String creator; | private String creator; | ||||
@@ -81,6 +65,9 @@ public class Meeting implements Serializable { | |||||
@ApiModelProperty("是否停止随机邀请") | @ApiModelProperty("是否停止随机邀请") | ||||
private Boolean inviteStopped; | private Boolean inviteStopped; | ||||
@ApiModelProperty("是否确认名单") | |||||
private Boolean confirmedRoster; | |||||
@ApiModelProperty("举办单位") | @ApiModelProperty("举办单位") | ||||
private String holdOrg; | private String holdOrg; | ||||
@@ -90,4 +77,20 @@ public class Meeting implements Serializable { | |||||
@ApiModelProperty("是否为内部项目") | @ApiModelProperty("是否为内部项目") | ||||
private Boolean isInnerProject; | private Boolean isInnerProject; | ||||
@ApiModelProperty("创建人ID") | |||||
@TableField(fill = FieldFill.INSERT) | |||||
private Long createBy; | |||||
@ApiModelProperty("创建时间") | |||||
@TableField(fill = FieldFill.INSERT) | |||||
private LocalDateTime createOn; | |||||
@ApiModelProperty("修改人ID") | |||||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||||
private Long updateBy; | |||||
@ApiModelProperty("修改时间") | |||||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||||
private LocalDateTime updateOn; | |||||
} | } |
@@ -47,9 +47,14 @@ public class MeetingExpert implements Serializable { | |||||
private String mobile; | private String mobile; | ||||
private String expertName; | |||||
@ApiModelProperty("当前状态") | @ApiModelProperty("当前状态") | ||||
private Integer status; | private Integer status; | ||||
@ApiModelProperty("是否是专家组长") | |||||
private Boolean isHeadman; | |||||
@ApiModelProperty("前一个状态") | @ApiModelProperty("前一个状态") | ||||
private Integer preStatus; | private Integer preStatus; | ||||
@@ -68,6 +73,5 @@ public class MeetingExpert implements Serializable { | |||||
private String submitKey; | private String submitKey; | ||||
private String expertName; | |||||
} | } |
@@ -18,14 +18,15 @@ import java.util.Arrays; | |||||
public enum ExpertAttendStatusEnum { | public enum ExpertAttendStatusEnum { | ||||
NOTICING("通知中", 0), | NOTICING("通知中", 0), | ||||
NOT_ANSWERED("未应答", 1), | |||||
UNANSWERED("未应答", 1), | |||||
REPLACED("已替换", 2), | REPLACED("已替换", 2), | ||||
AGREED("同意参加", 3), | AGREED("同意参加", 3), | ||||
REFUSED("拒绝参加", 4), | REFUSED("拒绝参加", 4), | ||||
CANCELED("已移除", 5), | |||||
ON_LEAVE("已请假", 6); | |||||
REMOVED("已移除", 5), | |||||
ON_LEAVE("已请假", 6), | |||||
RELEASED("已释放", 7); | |||||
private final String desc; | |||||
private final String value; | |||||
private final Integer code; | private final Integer code; | ||||
public boolean eq(Integer code) { | public boolean eq(Integer code) { | ||||
@@ -1,32 +1,32 @@ | |||||
package com.ningdatech.pmapi.meeting.entity.enumeration; | package com.ningdatech.pmapi.meeting.entity.enumeration; | ||||
import lombok.AllArgsConstructor; | |||||
import lombok.Getter; | import lombok.Getter; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
/** | /** | ||||
* <p> | * <p> | ||||
* MeetingDateTermType-会议日期类型 | |||||
* MeetingDateTermType | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author WendyYang | * @author WendyYang | ||||
* @since 09:54 2022/8/15 | * @since 09:54 2022/8/15 | ||||
*/ | */ | ||||
@Getter | @Getter | ||||
public enum MeetingDateTermType { | |||||
@AllArgsConstructor | |||||
public enum MeetingDateTermTypeEnum { | |||||
/** | |||||
* 会议日期类型 | |||||
*/ | |||||
ONE_DAY(1, "一天"), | ONE_DAY(1, "一天"), | ||||
MORE_THAN_ONE(2, "两天及以上"); | MORE_THAN_ONE(2, "两天及以上"); | ||||
private final Integer code; | private final Integer code; | ||||
private final String name; | |||||
private final String value; | |||||
MeetingDateTermType(Integer code, String name) { | |||||
this.code = code; | |||||
this.name = name; | |||||
} | |||||
public static MeetingDateTermType getByCode(Integer code) { | |||||
public static MeetingDateTermTypeEnum getByCode(Integer code) { | |||||
return Arrays.stream(values()) | return Arrays.stream(values()) | ||||
.filter(w -> w.getCode().equals(code)) | .filter(w -> w.getCode().equals(code)) | ||||
.findFirst() | .findFirst() |
@@ -0,0 +1,29 @@ | |||||
package com.ningdatech.pmapi.meeting.entity.req; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import javax.validation.constraints.NotNull; | |||||
/** | |||||
* <p> | |||||
* 确认参加参数类 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 08:59 2022/8/10 | |||||
*/ | |||||
@Data | |||||
@ApiModel("确认参加") | |||||
public class ExpertConfirmReq { | |||||
@NotNull(message = "会议ID不能为空") | |||||
@ApiModelProperty("会议ID") | |||||
private Long meetingId; | |||||
@NotNull(message = "专家会议ID不能为空") | |||||
@ApiModelProperty("专家会议ID") | |||||
private Long expertMeetingId; | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.ningdatech.pmapi.meeting.entity.req; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
/** | |||||
* <p> | |||||
* MeetingExpertIdReq | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 14:11 2023/3/3 | |||||
*/ | |||||
@Data | |||||
public class MeetingExpertIdReq { | |||||
@ApiModelProperty("专家会议ID") | |||||
private Long expertMeetingId; | |||||
} |
@@ -3,13 +3,12 @@ package com.ningdatech.pmapi.meeting.entity.vo; | |||||
import io.swagger.annotations.ApiModel; | import io.swagger.annotations.ApiModel; | ||||
import io.swagger.annotations.ApiModelProperty; | import io.swagger.annotations.ApiModelProperty; | ||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | |||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
* <p> | * <p> | ||||
* ExpertInviteDetailVo | |||||
* ExpertInviteDetailVO | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author WendyYang | * @author WendyYang | ||||
@@ -19,73 +18,13 @@ import java.util.List; | |||||
@ApiModel("专家邀请情况实体") | @ApiModel("专家邀请情况实体") | ||||
public class ExpertInviteDetailVO { | public class ExpertInviteDetailVO { | ||||
@Data | |||||
@EqualsAndHashCode(callSuper = true) | |||||
@ApiModel("最终参与名单实体") | |||||
public static class ExpertAttendListItemVO extends ExpertBasicInfoVO { | |||||
private Long meetingId; | |||||
private Long expertMeetingId; | |||||
@ApiModelProperty("邀请方式") | |||||
private String inviteType; | |||||
} | |||||
@Data | |||||
@EqualsAndHashCode(callSuper = true) | |||||
@ApiModel("随机邀请名单实体") | |||||
public static class RandomInviteListItemVO extends ExpertBasicInfoVO { | |||||
@ApiModelProperty("会议ID") | |||||
private Long meetingId; | |||||
@ApiModelProperty("专家会议ID") | |||||
private Long expertMeetingId; | |||||
@ApiModelProperty("电话通知状态") | |||||
private String noticeStatus; | |||||
@ApiModelProperty("邀请结果") | |||||
private String confirmResult; | |||||
@ApiModelProperty("邀请状态") | |||||
private Integer status; | |||||
} | |||||
@ApiModelProperty("参与数量总计") | |||||
private Integer attendTotal; | |||||
@ApiModelProperty("随机邀请参与数量") | |||||
private Integer randomAttend; | |||||
@ApiModelProperty("指定邀请参与数量") | |||||
private Integer appointAttend; | |||||
@ApiModelProperty("是否已停止邀请") | @ApiModelProperty("是否已停止邀请") | ||||
private Boolean invitedStopped; | private Boolean invitedStopped; | ||||
@ApiModelProperty("最终参与名单") | |||||
private List<ExpertAttendListItemVO> attendList; | |||||
@ApiModelProperty("随机邀请名单") | |||||
private List<RandomInviteListItemVO> randomInviteList; | |||||
@ApiModelProperty("指定邀请名单") | |||||
private List<RandomInviteListItemVO> appointInviteList; | |||||
public void addAttendList(ExpertAttendListItemVO attend) { | |||||
this.attendList.add(attend); | |||||
} | |||||
public void addRandomInviteList(RandomInviteListItemVO randomInvite) { | |||||
this.randomInviteList.add(randomInvite); | |||||
} | |||||
@ApiModelProperty("是否已确认名单") | |||||
private Boolean confirmedRoster; | |||||
public void addAppointInviteList(RandomInviteListItemVO appointInvite) { | |||||
this.appointInviteList.add(appointInvite); | |||||
} | |||||
@ApiModelProperty("邀请名单") | |||||
private List<RandomInviteListItemVO> inviteExpertList; | |||||
} | } |
@@ -0,0 +1,36 @@ | |||||
package com.ningdatech.pmapi.meeting.entity.vo; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
/** | |||||
* <p> | |||||
* RandomInviteListItemVO | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 16:48 2023/3/3 | |||||
*/ | |||||
@Data | |||||
@ApiModel("邀请名单实体") | |||||
@EqualsAndHashCode(callSuper = true) | |||||
public class RandomInviteListItemVO extends ExpertBasicInfoVO { | |||||
@ApiModelProperty("会议ID") | |||||
private Long meetingId; | |||||
@ApiModelProperty("专家会议ID") | |||||
private Long expertMeetingId; | |||||
@ApiModelProperty("电话通知状态") | |||||
private String noticeStatus; | |||||
@ApiModelProperty("邀请结果") | |||||
private String confirmResult; | |||||
@ApiModelProperty("邀请状态") | |||||
private Integer status; | |||||
} |
@@ -17,7 +17,6 @@ import com.ningdatech.pmapi.meeting.entity.dto.AvoidInfoDTO; | |||||
import com.ningdatech.pmapi.meeting.entity.dto.MeetingAndAttendStatusDTO; | import com.ningdatech.pmapi.meeting.entity.dto.MeetingAndAttendStatusDTO; | ||||
import com.ningdatech.pmapi.meeting.entity.dto.MeetingBasicDTO; | import com.ningdatech.pmapi.meeting.entity.dto.MeetingBasicDTO; | ||||
import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | ||||
import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatusEnum; | |||||
import com.ningdatech.pmapi.meeting.entity.req.MeetingListReq; | import com.ningdatech.pmapi.meeting.entity.req.MeetingListReq; | ||||
import com.ningdatech.pmapi.meeting.entity.vo.ExpertBasicInfoVO; | import com.ningdatech.pmapi.meeting.entity.vo.ExpertBasicInfoVO; | ||||
import com.ningdatech.pmapi.meeting.entity.vo.MeetingByManagerVO; | import com.ningdatech.pmapi.meeting.entity.vo.MeetingByManagerVO; | ||||
@@ -184,13 +183,13 @@ public class MeetingManageHelper { | |||||
switch (ExpertAttendStatusEnum.getByCode(w.getStatus())) { | switch (ExpertAttendStatusEnum.getByCode(w.getStatus())) { | ||||
case REFUSED: | case REFUSED: | ||||
throw BizException.wrap("专家%s已拒绝参加", expertName); | throw BizException.wrap("专家%s已拒绝参加", expertName); | ||||
case CANCELED: | |||||
case REMOVED: | |||||
throw BizException.wrap("专家%s已被移除", expertName); | throw BizException.wrap("专家%s已被移除", expertName); | ||||
case REPLACED: | case REPLACED: | ||||
switch (ExpertAttendStatusEnum.getByCode(w.getPreStatus())) { | switch (ExpertAttendStatusEnum.getByCode(w.getPreStatus())) { | ||||
case REFUSED: | case REFUSED: | ||||
throw BizException.wrap("专家%s已拒绝参加", expertName); | throw BizException.wrap("专家%s已拒绝参加", expertName); | ||||
case CANCELED: | |||||
case REMOVED: | |||||
throw BizException.wrap("专家%s已被移除", expertName); | throw BizException.wrap("专家%s已被移除", expertName); | ||||
default: | default: | ||||
break; | break; | ||||
@@ -409,7 +409,7 @@ public class ExpertInviteManage { | |||||
removeExpertIds.addAll(tempRefused); | removeExpertIds.addAll(tempRefused); | ||||
}); | }); | ||||
// 被取消的也不可以被再次抽中 | // 被取消的也不可以被再次抽中 | ||||
BizUtils.notEmpty(expertIdGroupByStatus.get(ExpertAttendStatusEnum.CANCELED), w -> { | |||||
BizUtils.notEmpty(expertIdGroupByStatus.get(ExpertAttendStatusEnum.REMOVED), w -> { | |||||
List<Long> tempCanceled = CollUtils.fieldList(w, MeetingExpert::getExpertId); | List<Long> tempCanceled = CollUtils.fieldList(w, MeetingExpert::getExpertId); | ||||
removeExpertIds.addAll(tempCanceled); | removeExpertIds.addAll(tempCanceled); | ||||
}); | }); | ||||
@@ -417,7 +417,7 @@ public class ExpertInviteManage { | |||||
BizUtils.notEmpty(expertIdGroupByStatus.get(ExpertAttendStatusEnum.REPLACED), w -> { | BizUtils.notEmpty(expertIdGroupByStatus.get(ExpertAttendStatusEnum.REPLACED), w -> { | ||||
for (MeetingExpert me : w) { | for (MeetingExpert me : w) { | ||||
BizUtils.notNull(me.getPreStatus(), preStatus -> { | BizUtils.notNull(me.getPreStatus(), preStatus -> { | ||||
if (ExpertAttendStatusEnum.REFUSED.eq(preStatus) || ExpertAttendStatusEnum.CANCELED.eq(preStatus)) { | |||||
if (ExpertAttendStatusEnum.REFUSED.eq(preStatus) || ExpertAttendStatusEnum.REMOVED.eq(preStatus)) { | |||||
removeExpertIds.add(me.getExpertId()); | removeExpertIds.add(me.getExpertId()); | ||||
} | } | ||||
}); | }); | ||||
@@ -16,7 +16,6 @@ import com.ningdatech.basic.model.PageVo; | |||||
import com.ningdatech.basic.util.CollUtils; | import com.ningdatech.basic.util.CollUtils; | ||||
import com.ningdatech.basic.util.ValidUtil; | import com.ningdatech.basic.util.ValidUtil; | ||||
import com.ningdatech.cache.lock.DistributedLock; | import com.ningdatech.cache.lock.DistributedLock; | ||||
import com.ningdatech.file.service.FileService; | |||||
import com.ningdatech.pmapi.common.helper.RegionCacheHelper; | import com.ningdatech.pmapi.common.helper.RegionCacheHelper; | ||||
import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; | import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; | ||||
import com.ningdatech.pmapi.expert.helper.PermissionCheckHelper; | import com.ningdatech.pmapi.expert.helper.PermissionCheckHelper; | ||||
@@ -29,8 +28,6 @@ import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertInviteTypeEnum; | |||||
import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatusEnum; | import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatusEnum; | ||||
import com.ningdatech.pmapi.meeting.entity.req.*; | import com.ningdatech.pmapi.meeting.entity.req.*; | ||||
import com.ningdatech.pmapi.meeting.entity.vo.*; | import com.ningdatech.pmapi.meeting.entity.vo.*; | ||||
import com.ningdatech.pmapi.meeting.entity.vo.ExpertInviteDetailVO.ExpertAttendListItemVO; | |||||
import com.ningdatech.pmapi.meeting.entity.vo.ExpertInviteDetailVO.RandomInviteListItemVO; | |||||
import com.ningdatech.pmapi.meeting.helper.ExpertInviteHelper; | import com.ningdatech.pmapi.meeting.helper.ExpertInviteHelper; | ||||
import com.ningdatech.pmapi.meeting.helper.MeetingManageHelper; | import com.ningdatech.pmapi.meeting.helper.MeetingManageHelper; | ||||
import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; | import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; | ||||
@@ -42,7 +39,6 @@ import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.sys.model.dto.RegionDTO; | import com.ningdatech.pmapi.sys.model.dto.RegionDTO; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | ||||
import com.ningdatech.pmapi.user.service.IUserInfoService; | |||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
@@ -73,7 +69,6 @@ public class MeetingManage { | |||||
private final IExpertInviteAvoidRuleService inviteAvoidRuleService; | private final IExpertInviteAvoidRuleService inviteAvoidRuleService; | ||||
private final IExpertInviteRuleService inviteRuleService; | private final IExpertInviteRuleService inviteRuleService; | ||||
private final IExpertUserFullInfoService expertUserFullInfoService; | private final IExpertUserFullInfoService expertUserFullInfoService; | ||||
private final FileService fileService; | |||||
private final TagCache tagCache; | private final TagCache tagCache; | ||||
private final DictionaryCache dictionaryCache; | private final DictionaryCache dictionaryCache; | ||||
private final IMeetingExpertService meetingExpertService; | private final IMeetingExpertService meetingExpertService; | ||||
@@ -83,7 +78,6 @@ public class MeetingManage { | |||||
private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | ||||
private final DistributedLock distributedLock; | private final DistributedLock distributedLock; | ||||
private final PermissionCheckHelper permissionCheckHelper; | private final PermissionCheckHelper permissionCheckHelper; | ||||
private final IUserInfoService userInfoService; | |||||
private final IProjectService projectService; | private final IProjectService projectService; | ||||
private final IMeetingInnerProjectService meetingInnerProjectService; | private final IMeetingInnerProjectService meetingInnerProjectService; | ||||
private final IMeetingOuterProjectService meetingOuterProjectService; | private final IMeetingOuterProjectService meetingOuterProjectService; | ||||
@@ -116,7 +110,8 @@ public class MeetingManage { | |||||
meeting.setHoldOrgCode(userDetail.getOrganizationCode()); | meeting.setHoldOrgCode(userDetail.getOrganizationCode()); | ||||
meeting.setRegionCode(userDetail.getRegionCode()); | meeting.setRegionCode(userDetail.getRegionCode()); | ||||
meeting.setCreator(userDetail.getUsername()); | meeting.setCreator(userDetail.getUsername()); | ||||
meeting.setInviteStopped(true); | |||||
meeting.setInviteStopped(Boolean.FALSE); | |||||
meeting.setConfirmedRoster(Boolean.FALSE); | |||||
meetingService.save(meeting); | meetingService.save(meeting); | ||||
if (meetingBasic.getIsInnerProject()) { | if (meetingBasic.getIsInnerProject()) { | ||||
List<MeetingInnerProject> projects = meetingBasic.getProjectIdList().stream().map(w -> { | List<MeetingInnerProject> projects = meetingBasic.getProjectIdList().stream().map(w -> { | ||||
@@ -351,13 +346,14 @@ public class MeetingManage { | |||||
return detail; | return detail; | ||||
} | } | ||||
public ExpertInviteDetailVO inviteDetail(Long meetingId) { | |||||
ExpertInviteDetailVO result = new ExpertInviteDetailVO(); | |||||
public ExpertInviteDetailVO inviteExpertList(Long meetingId) { | |||||
Meeting meeting = meetingService.getById(meetingId); | Meeting meeting = meetingService.getById(meetingId); | ||||
if (Objects.isNull(meeting)) { | |||||
throw new BizException("该会议信息不存在"); | |||||
if (meeting == null) { | |||||
throw BizException.wrap("该会议信息不存在"); | |||||
} | } | ||||
ExpertInviteDetailVO result = new ExpertInviteDetailVO(); | |||||
result.setInvitedStopped(meeting.getInviteStopped()); | result.setInvitedStopped(meeting.getInviteStopped()); | ||||
result.setConfirmedRoster(meeting.getConfirmedRoster()); | |||||
List<MeetingExpert> experts = meetingExpertService.listByMeetingId(meetingId); | List<MeetingExpert> experts = meetingExpertService.listByMeetingId(meetingId); | ||||
if (experts.isEmpty()) { | if (experts.isEmpty()) { | ||||
return result; | return result; | ||||
@@ -376,14 +372,11 @@ public class MeetingManage { | |||||
if (w.getStatus().equals(ExpertAttendStatusEnum.AGREED.getCode())) { | if (w.getStatus().equals(ExpertAttendStatusEnum.AGREED.getCode())) { | ||||
attendList.add(w); | attendList.add(w); | ||||
if (randomInvite) { | if (randomInvite) { | ||||
result.setRandomAttend(result.getRandomAttend() + 1); | |||||
} else { | } else { | ||||
result.setAppointAttend(result.getAppointAttend() + 1); | |||||
} | } | ||||
} | } | ||||
expertIds.add(w.getExpertId()); | expertIds.add(w.getExpertId()); | ||||
}); | }); | ||||
result.setAttendTotal(attendList.size()); | |||||
Map<Long, ExpertBasicInfoVO> expertBasicInfoVoMap = meetingManageHelper.getExpertBasicInfo(expertIds); | Map<Long, ExpertBasicInfoVO> expertBasicInfoVoMap = meetingManageHelper.getExpertBasicInfo(expertIds); | ||||
Function<MeetingExpert, RandomInviteListItemVO> mapping = sme -> { | Function<MeetingExpert, RandomInviteListItemVO> mapping = sme -> { | ||||
ExpertBasicInfoVO basicInfoVo = expertBasicInfoVoMap.get(sme.getExpertId()); | ExpertBasicInfoVO basicInfoVo = expertBasicInfoVoMap.get(sme.getExpertId()); | ||||
@@ -393,38 +386,18 @@ public class MeetingManage { | |||||
item.setExpertMeetingId(sme.getId()); | item.setExpertMeetingId(sme.getId()); | ||||
ExpertAttendStatusEnum status = ExpertAttendStatusEnum.getByCode(sme.getStatus()); | ExpertAttendStatusEnum status = ExpertAttendStatusEnum.getByCode(sme.getStatus()); | ||||
if (status.equals(ExpertAttendStatusEnum.NOTICING)) { | if (status.equals(ExpertAttendStatusEnum.NOTICING)) { | ||||
item.setNoticeStatus(status.getDesc()); | |||||
item.setNoticeStatus(status.getValue()); | |||||
item.setConfirmResult(StrUtil.EMPTY); | item.setConfirmResult(StrUtil.EMPTY); | ||||
} else { | } else { | ||||
item.setNoticeStatus("已通知"); | item.setNoticeStatus("已通知"); | ||||
item.setConfirmResult(status.getDesc()); | |||||
item.setConfirmResult(status.getValue()); | |||||
} | } | ||||
return item; | return item; | ||||
}; | }; | ||||
// 随机邀请列表 | |||||
randomList.forEach(w -> result.addRandomInviteList(mapping.apply(w))); | |||||
// 指定抽取列表 | |||||
appointList.forEach(w -> result.addAppointInviteList(mapping.apply(w))); | |||||
// 确定参加列表 | // 确定参加列表 | ||||
attendList.forEach(w -> { | |||||
ExpertBasicInfoVO expertBasicInfoVo = expertBasicInfoVoMap.get(w.getExpertId()); | |||||
ExpertAttendListItemVO item = BeanUtil.copyProperties(expertBasicInfoVo, ExpertAttendListItemVO.class); | |||||
item.setInviteType(ExpertInviteTypeEnum.getByCode(w.getInviteType()).getName()); | |||||
result.addAttendList(item); | |||||
}); | |||||
return result; | return result; | ||||
} | } | ||||
private boolean meetingInfoChange(Meeting old, Meeting current) { | |||||
if (!old.getStartTime().equals(current.getStartTime())) { | |||||
return Boolean.TRUE; | |||||
} | |||||
if (!old.getRegionCode().equals(current.getRegionCode())) { | |||||
return Boolean.TRUE; | |||||
} | |||||
return Boolean.FALSE; | |||||
} | |||||
/** | /** | ||||
* 会议基本信息修改 | * 会议基本信息修改 | ||||
* | * | ||||
@@ -506,7 +479,7 @@ public class MeetingManage { | |||||
public void expertRemove(ExpertRemoveReq po) { | public void expertRemove(ExpertRemoveReq po) { | ||||
LambdaUpdateWrapper<MeetingExpert> update = Wrappers.lambdaUpdate(MeetingExpert.class) | LambdaUpdateWrapper<MeetingExpert> update = Wrappers.lambdaUpdate(MeetingExpert.class) | ||||
.eq(MeetingExpert::getId, po.getExpertMeetingId()) | .eq(MeetingExpert::getId, po.getExpertMeetingId()) | ||||
.set(MeetingExpert::getStatus, ExpertAttendStatusEnum.CANCELED.getCode()); | |||||
.set(MeetingExpert::getStatus, ExpertAttendStatusEnum.REMOVED.getCode()); | |||||
meetingExpertService.update(update); | meetingExpertService.update(update); | ||||
} | } | ||||
@@ -582,32 +555,6 @@ public class MeetingManage { | |||||
meetingExpertService.saveBatch(expertList); | meetingExpertService.saveBatch(expertList); | ||||
} | } | ||||
public void sendMeetingNotice(Long meetingId) { | |||||
String key = "SEND_MEETING_NOTICE:" + meetingId; | |||||
if (!distributedLock.lock(key, RETRY_TIMES)) { | |||||
throw BizException.wrap("正在下发会议通知"); | |||||
} | |||||
try { | |||||
Meeting meeting = meetingService.getById(meetingId); | |||||
Assert.isTrue(meeting.getInviteStopped(), "随机邀请未结束"); | |||||
int noticeCount = meetingExpertService.countExpertByStatusAndMeetingId(ExpertAttendStatusEnum.NOTICING, meetingId, null); | |||||
Assert.isTrue(noticeCount == 0, "存在未确认完成的专家,暂无法下发会议通知"); | |||||
LambdaUpdateWrapper<Meeting> update = Wrappers.lambdaUpdate(Meeting.class) | |||||
.eq(Meeting::getId, meetingId); | |||||
meetingService.update(update); | |||||
// 发送会议通知 | |||||
List<MeetingExpert> experts = meetingExpertService.listAgreedExperts(Collections.singletonList(meetingId)); | |||||
if (!experts.isEmpty()) { | |||||
// TODO | |||||
// String meetingType = dictionaryCache.getByCode(meeting.getType()).getName(); | |||||
// List<SendSmsContext> contexts = YxtSmsContextBuilder.smsToExpertBySendNotice(meeting, experts, meetingType); | |||||
// yxtCallOrSmsHelper.sendSms(contexts); | |||||
} | |||||
} finally { | |||||
distributedLock.releaseLock(key); | |||||
} | |||||
} | |||||
public void stopRandomInvite(Long meetingId) { | public void stopRandomInvite(Long meetingId) { | ||||
expertInviteTask.cancelByMeetingId(meetingId); | expertInviteTask.cancelByMeetingId(meetingId); | ||||
} | } | ||||
@@ -649,12 +596,16 @@ public class MeetingManage { | |||||
public ExpertInvitationDetailVO expertInvitationDetail(Long meetingId, Long expertId) { | public ExpertInvitationDetailVO expertInvitationDetail(Long meetingId, Long expertId) { | ||||
Long userId = expertId == null ? LoginUserUtil.getUserId() : expertId; | Long userId = expertId == null ? LoginUserUtil.getUserId() : expertId; | ||||
MeetingExpert me = meetingExpertService.getByMeetingIdAndExpertId(meetingId, userId); | MeetingExpert me = meetingExpertService.getByMeetingIdAndExpertId(meetingId, userId); | ||||
Assert.notNull(me, "未被邀请参加"); | |||||
Assert.isTrue(ExpertAttendStatusEnum.AGREED.eq(me.getStatus()), "未确认参加"); | |||||
ExpertUserFullInfo expertInfo = expertUserFullInfoService.getByUserId(userId); | |||||
if (me == null) { | |||||
throw BizException.wrap("未被邀请参加此会议"); | |||||
} | |||||
if (ExpertAttendStatusEnum.AGREED.eq(me.getStatus())) { | |||||
throw BizException.wrap("未确认参加此会议"); | |||||
} | |||||
ExpertUserFullInfo userInfo = expertUserFullInfoService.getByUserId(userId); | |||||
Meeting meeting = meetingService.getById(meetingId); | Meeting meeting = meetingService.getById(meetingId); | ||||
return ExpertInvitationDetailVO.builder() | return ExpertInvitationDetailVO.builder() | ||||
.expertName(expertInfo.getExpertName()) | |||||
.expertName(userInfo.getExpertName()) | |||||
.holdOrg(meeting.getHoldOrg()) | .holdOrg(meeting.getHoldOrg()) | ||||
.meetingName(meeting.getName()) | .meetingName(meeting.getName()) | ||||
.startTime(meeting.getStartTime()) | .startTime(meeting.getStartTime()) | ||||
@@ -665,18 +616,95 @@ public class MeetingManage { | |||||
.build(); | .build(); | ||||
} | } | ||||
public void confirmAttendByManager(ExpertRemoveReq po) { | |||||
MeetingExpert meetingExpert = meetingExpertService.getById(po.getExpertMeetingId()); | |||||
if (meetingExpert.getStatus().equals(ExpertAttendStatusEnum.NOTICING.getCode())) { | |||||
public void confirmAttendByManager(ExpertConfirmReq req) { | |||||
String key = "CONFIRM_ATTEND:" + req.getExpertMeetingId(); | |||||
if (!distributedLock.lock(key, RETRY_TIMES)) { | |||||
throw BizException.wrap("确认参加失败,请重试!"); | |||||
} | |||||
try { | |||||
MeetingExpert me = meetingExpertService.getById(req.getExpertMeetingId()); | |||||
if (!ExpertAttendStatusEnum.NOTICING.eq(me.getStatus())) { | |||||
throw BizException.wrap("确认参加失败,请重试!"); | |||||
} | |||||
LambdaUpdateWrapper<MeetingExpert> update = Wrappers.lambdaUpdate(MeetingExpert.class) | LambdaUpdateWrapper<MeetingExpert> update = Wrappers.lambdaUpdate(MeetingExpert.class) | ||||
.set(MeetingExpert::getStatus, ExpertAttendStatusEnum.AGREED.getCode()) | .set(MeetingExpert::getStatus, ExpertAttendStatusEnum.AGREED.getCode()) | ||||
.set(MeetingExpert::getUpdateOn, LocalDateTime.now()) | |||||
.set(MeetingExpert::getUpdateBy, LoginUserUtil.getUserId()) | |||||
.eq(MeetingExpert::getId, po.getExpertMeetingId()); | |||||
.eq(MeetingExpert::getId, req.getExpertMeetingId()); | |||||
meetingExpertService.update(update); | meetingExpertService.update(update); | ||||
} else { | |||||
ExpertAttendStatusEnum status = ExpertAttendStatusEnum.getByCode(meetingExpert.getStatus()); | |||||
throw BizException.wrap("该专家" + status.getDesc()); | |||||
} finally { | |||||
distributedLock.releaseLock(key); | |||||
} | |||||
} | |||||
public void releaseExperts(MeetingCancelReq req) { | |||||
String key = "EXPERT_RELEASE:" + req.getMeetingId(); | |||||
if (!distributedLock.lock(key, RETRY_TIMES)) { | |||||
throw BizException.wrap("释放专家失败,请重试!"); | |||||
} | |||||
try { | |||||
Meeting meeting = meetingService.getById(req.getMeetingId()); | |||||
if (MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||||
throw BizException.wrap("会议已取消"); | |||||
} | |||||
LambdaUpdateWrapper<MeetingExpert> update = Wrappers.lambdaUpdate(MeetingExpert.class) | |||||
.set(MeetingExpert::getStatus, ExpertAttendStatusEnum.RELEASED.getCode()) | |||||
.eq(MeetingExpert::getMeetingId, req.getMeetingId()); | |||||
meetingExpertService.update(update); | |||||
} finally { | |||||
distributedLock.releaseLock(key); | |||||
} | |||||
} | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void setUpHeadman(ExpertConfirmReq req) { | |||||
String key = "SETUP_HEADMAN:" + req.getMeetingId(); | |||||
if (!distributedLock.lock(key, RETRY_TIMES)) { | |||||
throw BizException.wrap("设置专家组长失败,请重试!"); | |||||
} | |||||
try { | |||||
Meeting meeting = meetingService.getById(req.getMeetingId()); | |||||
if (MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||||
throw BizException.wrap("会议已取消"); | |||||
} | |||||
LambdaUpdateWrapper<MeetingExpert> cancel = Wrappers.lambdaUpdate(MeetingExpert.class) | |||||
.set(MeetingExpert::getIsHeadman, Boolean.FALSE) | |||||
.eq(MeetingExpert::getIsHeadman, Boolean.TRUE) | |||||
.eq(MeetingExpert::getMeetingId, req.getMeetingId()); | |||||
meetingExpertService.update(cancel); | |||||
MeetingExpert headman = meetingExpertService.getById(req.getExpertMeetingId()); | |||||
if (!ExpertAttendStatusEnum.AGREED.eq(headman.getStatus())) { | |||||
ExpertAttendStatusEnum status = ExpertAttendStatusEnum.getByCode(headman.getStatus()); | |||||
throw BizException.wrap("该专家处于:%s状态,不能被设置为专家组长!", status.getValue()); | |||||
} | |||||
LambdaUpdateWrapper<MeetingExpert> setup = Wrappers.lambdaUpdate(MeetingExpert.class) | |||||
.set(MeetingExpert::getIsHeadman, Boolean.TRUE) | |||||
.eq(MeetingExpert::getId, req.getExpertMeetingId()); | |||||
meetingExpertService.update(setup); | |||||
} finally { | |||||
distributedLock.releaseLock(key); | |||||
} | |||||
} | |||||
public void confirmedRoster(Long meetingId) { | |||||
String key = "MEETING_RESEND_SMS:" + meetingId; | |||||
if (!distributedLock.lock(key, RETRY_TIMES)) { | |||||
throw BizException.wrap("请刷新后重试!"); | |||||
} | |||||
try { | |||||
Meeting meeting = meetingService.getById(meetingId); | |||||
if (!MeetingStatusEnum.NORMAL.eq(meeting.getStatus())) { | |||||
throw BizException.wrap("请刷新后重试!"); | |||||
} | |||||
if (!meeting.getConfirmedRoster()) { | |||||
// 首次确认的 | |||||
LambdaUpdateWrapper<Meeting> update = Wrappers.lambdaUpdate(Meeting.class); | |||||
update.set(Meeting::getConfirmedRoster, Boolean.TRUE); | |||||
update.eq(Meeting::getId, meetingId); | |||||
meetingService.update(update); | |||||
} | |||||
List<MeetingExpert> experts = meetingExpertService.listAgreedExperts(meetingId); | |||||
// TODO 发送会议通知 | |||||
} finally { | |||||
distributedLock.releaseLock(key); | |||||
} | } | ||||
} | } | ||||
@@ -61,7 +61,7 @@ public class MeetingExpertServiceImpl extends ServiceImpl<MeetingExpertMapper, M | |||||
ExpertAttendStatusEnum attendStatus = ExpertAttendStatusEnum.getByCode(item.getStatus()); | ExpertAttendStatusEnum attendStatus = ExpertAttendStatusEnum.getByCode(item.getStatus()); | ||||
if (item.getInviteType().equals(ExpertInviteTypeEnum.APPOINT.getCode())) { | if (item.getInviteType().equals(ExpertInviteTypeEnum.APPOINT.getCode())) { | ||||
// 被替换和已取消的不计数 | // 被替换和已取消的不计数 | ||||
if (attendStatus.equals(ExpertAttendStatusEnum.CANCELED) | |||||
if (attendStatus.equals(ExpertAttendStatusEnum.REMOVED) | |||||
|| attendStatus.equals(ExpertAttendStatusEnum.REPLACED)) { | || attendStatus.equals(ExpertAttendStatusEnum.REPLACED)) { | ||||
return; | return; | ||||
} | } | ||||