diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/model/entity/KeyValDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/model/entity/KeyValDTO.java new file mode 100644 index 0000000..c932655 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/model/entity/KeyValDTO.java @@ -0,0 +1,28 @@ +package com.ningdatech.pmapi.common.model.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * KeyValueDTO + *

+ * + * @author WendyYang + * @since 16:40 2022/8/31 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class KeyValDTO { + + private K key; + + private V value; + + public static KeyValDTO of(K k, V v) { + return new KeyValDTO<>(k, v); + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/expert/model/dto/ModifyApplyExtraInfoDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/expert/model/dto/ModifyApplyExtraInfoDTO.java new file mode 100644 index 0000000..082c5fc --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/expert/model/dto/ModifyApplyExtraInfoDTO.java @@ -0,0 +1,25 @@ +package com.ningdatech.pmapi.expert.model.dto; + +import com.ningdatech.pmapi.common.model.FileBasicInfo; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.util.List; + +/** + * @author liuxinxin + * @date 2022/7/28 下午3:48 + */ +@Data +public class ModifyApplyExtraInfoDTO { + /** + * 情况说明 + */ + @NotBlank + private String factSheet; + + /** + * 证明材料 + */ + private List evidenceList; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/controller/ExpertLeaveController.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/controller/ExpertLeaveController.java new file mode 100644 index 0000000..df7443b --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/controller/ExpertLeaveController.java @@ -0,0 +1,70 @@ +package com.ningdatech.pmapi.leave.controller; + + +import com.ningdatech.basic.exception.BizException; +import com.ningdatech.basic.model.IdVo; +import com.ningdatech.basic.model.PageVo; +import com.ningdatech.pmapi.leave.entity.po.LeaveCreateReq; +import com.ningdatech.pmapi.leave.entity.po.LeaveListByCreatorReq; +import com.ningdatech.pmapi.leave.entity.vo.LeaveDetailVO; +import com.ningdatech.pmapi.leave.entity.vo.LeaveListItemVO; +import com.ningdatech.pmapi.leave.manage.LeaveManage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + *

+ * 前端控制器 + *

+ * + * @author WendyYang + * @since 2022-08-11 + */ +@Api(tags = "请假管理控制器") +@RestController +@AllArgsConstructor +@RequestMapping("/api/v1/leave/") +public class ExpertLeaveController { + + private final LeaveManage leaveManage; + + @ApiOperation("请假") + @PostMapping("/save") + public IdVo askForLeave(@Valid @RequestBody LeaveCreateReq po) { + return leaveManage.askForLeave(po); + } + + @ApiOperation("请假详情") + @GetMapping(value = {"/detail/{leaveId}", "/detail/{auditId}/byApply"}) + public LeaveDetailVO detail(@PathVariable(required = false) Long leaveId, + @PathVariable(required = false) Long auditId) { + if (ObjectUtils.allNull(leaveId, auditId)) { + throw BizException.wrap("请假ID或申请ID不能为空"); + } + return leaveManage.leaveDetail(leaveId, auditId); + } + + @ApiOperation("我的请假列表(发起人)") + @GetMapping("/leaveListByCreator") + public PageVo leaveListByCreator(LeaveListByCreatorReq po) { + return leaveManage.leaveListByCreator(po); + } + + @ApiOperation("销假") + @GetMapping("/endLeave") + public void endLeave(Long leaveId) { + leaveManage.endLeave(leaveId); + } + + @ApiOperation("撤销") + @GetMapping("/cancel") + public void cancelLeave(Long leaveId) { + leaveManage.cancel(leaveId); + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/domain/ExpertLeave.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/domain/ExpertLeave.java new file mode 100644 index 0000000..4aca8d3 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/domain/ExpertLeave.java @@ -0,0 +1,83 @@ +package com.ningdatech.pmapi.leave.entity.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 请假记录表 + *

+ * + * @author WendyYang + * @since 2022-08-11 + */ +@Data +@TableName("expert_leave") +@ApiModel(value = "ExpertLeave对象", description = "请假记录表") +public class ExpertLeave implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键") + @TableId(type = IdType.AUTO) + private Long id; + + @ApiModelProperty("请假类型") + private Integer type; + + @ApiModelProperty("请假说明") + private String remark; + + @ApiModelProperty("附件ID") + private String attachment; + + @ApiModelProperty("审核表ID") + private Long auditId; + + @ApiModelProperty("请假人ID") + private Long leaveUserId; + + @ApiModelProperty("创建人名称") + private String creator; + + @ApiModelProperty("创建人") + private Long createBy; + + @ApiModelProperty("创建时间") + private LocalDateTime createOn; + + @ApiModelProperty("修改人") + private Long updateBy; + + @ApiModelProperty("修改时间") + private LocalDateTime updateOn; + + @ApiModelProperty("请假开始时间") + private LocalDateTime startTime; + + @ApiModelProperty("请假结束时间") + private LocalDateTime endTime; + + @ApiModelProperty("销假时间") + private LocalDateTime cancelTime; + + @ApiModelProperty("固定时段模式") + private String fixedType; + + private Long meetingId; + + private Integer status; + + public void setUpdateAndCreate(Long createBy, LocalDateTime createOn) { + this.updateBy = this.createBy = createBy; + this.updateOn = this.createOn = createOn; + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/domain/ExpertLeaveDetail.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/domain/ExpertLeaveDetail.java new file mode 100644 index 0000000..f252b58 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/domain/ExpertLeaveDetail.java @@ -0,0 +1,49 @@ +package com.ningdatech.pmapi.leave.entity.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 专家请假详情表(维度:天) + *

+ * + * @author WendyYang + * @since 2022-08-11 + */ +@Data +@NoArgsConstructor +@TableName("expert_leave_detail") +@ApiModel(value = "ExpertLeaveDetail对象", description = "专家请假详情表(维度:天)") +public class ExpertLeaveDetail implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键") + @TableId(type = IdType.AUTO) + private Long id; + + @ApiModelProperty("专家请假ID") + private Long expertLeaveId; + + @ApiModelProperty("开始时间") + private LocalDateTime startTime; + + @ApiModelProperty("结束时间") + private LocalDateTime endTime; + + public ExpertLeaveDetail(Long expertLeaveId, LocalDateTime startTime, LocalDateTime endTime) { + this.expertLeaveId = expertLeaveId; + this.startTime = startTime; + this.endTime = endTime; + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/enumeration/LeaveStatusEnum.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/enumeration/LeaveStatusEnum.java new file mode 100644 index 0000000..5581add --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/enumeration/LeaveStatusEnum.java @@ -0,0 +1,45 @@ +package com.ningdatech.pmapi.leave.entity.enumeration; + +import lombok.Getter; + +import java.util.Arrays; + +/** + *

+ * LeaveStatus + *

+ * + * @author WendyYang + * @since 09:39 2022/8/12 + */ +@Getter +public enum LeaveStatusEnum { + + /** + * 请假状态 + */ + APPLYING(1, "审核中"), + PASSED(2, "审核通过"), + PASSED_END(3, "审核通过且销假"), + UN_PASSED(4, "审核不通过"), + CANCELED(5, "发起人撤销"); + private final Integer code; + private final String name; + + public boolean eq(Integer code) { + return this.getCode().equals(code); + } + + LeaveStatusEnum(Integer code, String name) { + this.code = code; + this.name = name; + } + + public static LeaveStatusEnum getByCode(Integer code) { + return Arrays.stream(values()) + .filter(w -> w.getCode().equals(code)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("无效的请假状态")); + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/enumeration/LeaveTypeEnum.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/enumeration/LeaveTypeEnum.java new file mode 100644 index 0000000..11b6467 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/enumeration/LeaveTypeEnum.java @@ -0,0 +1,41 @@ +package com.ningdatech.pmapi.leave.entity.enumeration; + +import lombok.Getter; + +import java.util.Arrays; + +/** + *

+ * LeaveType-请假类型 + *

+ * + * @author WendyYang + * @since 10:23 2022/8/11 + */ +@Getter +public enum LeaveTypeEnum { + + TEMPORARY(3, "临时请假"), + LONG_TERM(1, "长期请假"), + FIXED_TERM(2, "固定时段请假"); + + private final Integer code; + private final String name; + + public boolean eq(Integer code) { + return this.getCode().equals(code); + } + + LeaveTypeEnum(Integer code, String name) { + this.code = code; + this.name = name; + } + + public static LeaveTypeEnum getByCode(Integer code) { + return Arrays.stream(values()) + .filter(w -> w.getCode().equals(code)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("无效的请假类型")); + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/po/LeaveCreateReq.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/po/LeaveCreateReq.java new file mode 100644 index 0000000..fa4f0e0 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/po/LeaveCreateReq.java @@ -0,0 +1,73 @@ +package com.ningdatech.pmapi.leave.entity.po; + +import com.ningdatech.basic.exception.BizException; +import com.ningdatech.pmapi.leave.entity.enumeration.LeaveTypeEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.ObjectUtils; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * LeaveCreatePo + *

+ * + * @author WendyYang + * @since 10:30 2022/8/11 + */ +@Data +@ApiModel("请假创建实体") +public class LeaveCreateReq { + + @ApiModelProperty("请假类型:1 长期请假、2 固定时段请假、3 临时请假") + @NotNull(message = "请假类型不能为空") + private Integer type; + + @ApiModelProperty("请假开始时间") + private LocalDateTime startTime; + + @ApiModelProperty("请假结束时间") + private LocalDateTime endTime; + + @ApiModelProperty("请假说明") + @NotBlank(message = "请假说明不能为空") + private String postscript; + + @ApiModelProperty("附件ID") + private List attachments; + + @ApiModelProperty("固定时段") + private List fixedType; + + @ApiModelProperty("会议ID") + private Long meetingId; + + @ApiModelProperty("专家ID:管理员替专家请假时传参") + private Long expertId; + + public void paramCheck(LeaveTypeEnum leaveTypeEnum) { + if (leaveTypeEnum.equals(LeaveTypeEnum.TEMPORARY)) { + if (this.getMeetingId() == null) { + throw new BizException("会议ID不能为空"); + } + } else { + if (ObjectUtils.anyNull(this.getStartTime(), this.getEndTime())) { + throw new BizException("开始时间或结束时间不能为空"); + } + if (!this.getStartTime().isBefore(this.getEndTime())) { + throw new BizException("无效的请假时间"); + } + if (leaveTypeEnum.equals(LeaveTypeEnum.FIXED_TERM)) { + if (this.getFixedType() == null || this.getFixedType().isEmpty()) { + throw new BizException("固定时段不能为空"); + } + } + } + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/po/LeaveListByCreatorReq.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/po/LeaveListByCreatorReq.java new file mode 100644 index 0000000..3661c62 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/po/LeaveListByCreatorReq.java @@ -0,0 +1,43 @@ +package com.ningdatech.pmapi.leave.entity.po; + +import com.ningdatech.basic.model.PagePo; +import com.ningdatech.pmapi.sms.constant.DatePattern; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +/** + *

+ * LeaveListByCreatorPo + *

+ * + * @author WendyYang + * @since 19:32 2022/8/11 + */ +@Data +@ApiModel("我的请假列表参数实体") +@EqualsAndHashCode(callSuper = true) +public class LeaveListByCreatorReq extends PagePo { + + @ApiModelProperty("开始时间") + @DateTimeFormat(pattern = DatePattern.YMD_HMS) + private LocalDateTime startTime; + + @ApiModelProperty("结束时间") + @DateTimeFormat(pattern = DatePattern.YMD_HMS) + private LocalDateTime endTime; + + @ApiModelProperty("请假类型") + private Integer leaveType; + + @ApiModelProperty("审核状态") + private String auditStatus; + + @ApiModelProperty("专家ID") + private Long expertId; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/vo/LeaveDetailVO.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/vo/LeaveDetailVO.java new file mode 100644 index 0000000..ce91b39 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/vo/LeaveDetailVO.java @@ -0,0 +1,46 @@ +package com.ningdatech.pmapi.leave.entity.vo; + +import com.ningdatech.file.entity.vo.result.AttachFileVo; +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * LeaveDetailVo + *

+ * + * @author WendyYang + * @since 11:48 2022/8/12 + */ +@Data +@Builder +public class LeaveDetailVO { + + private Long id; + + private String postscript; + + private LocalDateTime startTime; + + private LocalDateTime endTime; + + private LocalDateTime actualEndTime; + + private Integer status; + + private List attachments; + + private Integer type; + + private List fixedType; + + private LocalDateTime createOn; + + private String createBy; + + private Long auditId; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/vo/LeaveListItemVO.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/vo/LeaveListItemVO.java new file mode 100644 index 0000000..ec9320f --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/entity/vo/LeaveListItemVO.java @@ -0,0 +1,61 @@ +package com.ningdatech.pmapi.leave.entity.vo; + +import com.ningdatech.file.entity.vo.result.AttachFileVo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * LeaveListItemByCreatorVo + *

+ * + * @author WendyYang + * @since 20:53 2022/8/11 + */ +@Data +@ApiModel("我得请假列表实体(发起人)") +public class LeaveListItemVO { + + @ApiModelProperty("请假ID") + private Long leaveId; + + @ApiModelProperty("审核ID") + private Long auditId; + + @ApiModelProperty("开始时间") + private LocalDateTime startTime; + + @ApiModelProperty("结束时间") + private LocalDateTime endTime; + + @ApiModelProperty("实际结束时间") + private LocalDateTime actualEndTime; + + @ApiModelProperty("请假说明") + private String postscript; + + @ApiModelProperty("说明材料") + private List attachments; + + @ApiModelProperty("请假类型") + private Integer leaveType; + + @ApiModelProperty("相关会议") + private String meetingName; + + @ApiModelProperty("审核状态") + private String auditStatus; + + @ApiModelProperty("状态") + private Integer status; + + @ApiModelProperty("审核意见") + private String auditOption; + + private LocalDateTime createOn; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/manage/LeaveManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/manage/LeaveManage.java new file mode 100644 index 0000000..e5df123 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/manage/LeaveManage.java @@ -0,0 +1,514 @@ +package com.ningdatech.pmapi.leave.manage; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +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.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ningdatech.basic.exception.BizException; +import com.ningdatech.basic.model.IdVo; +import com.ningdatech.basic.model.PagePo; +import com.ningdatech.basic.model.PageVo; +import com.ningdatech.basic.util.CollUtils; +import com.ningdatech.file.entity.vo.result.AttachFileVo; +import com.ningdatech.file.service.FileService; +import com.ningdatech.pmapi.common.model.FileBasicInfo; +import com.ningdatech.pmapi.common.model.entity.KeyValDTO; +import com.ningdatech.pmapi.common.util.BizUtils; +import com.ningdatech.pmapi.common.util.StrUtils; +import com.ningdatech.pmapi.expert.constant.ExpertApplyStatusEnum; +import com.ningdatech.pmapi.expert.constant.ExpertApplyTypeEnum; +import com.ningdatech.pmapi.expert.entity.ExpertMetaApply; +import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; +import com.ningdatech.pmapi.expert.model.dto.ModifyApplyExtraInfoDTO; +import com.ningdatech.pmapi.expert.service.IExpertMetaApplyService; +import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService; +import com.ningdatech.pmapi.leave.entity.domain.ExpertLeave; +import com.ningdatech.pmapi.leave.entity.domain.ExpertLeaveDetail; +import com.ningdatech.pmapi.leave.entity.enumeration.LeaveStatusEnum; +import com.ningdatech.pmapi.leave.entity.enumeration.LeaveTypeEnum; +import com.ningdatech.pmapi.leave.entity.po.LeaveCreateReq; +import com.ningdatech.pmapi.leave.entity.po.LeaveListByCreatorReq; +import com.ningdatech.pmapi.leave.entity.vo.LeaveDetailVO; +import com.ningdatech.pmapi.leave.entity.vo.LeaveListItemVO; +import com.ningdatech.pmapi.leave.service.IExpertLeaveDetailService; +import com.ningdatech.pmapi.leave.service.IExpertLeaveService; +import com.ningdatech.pmapi.meeting.entity.domain.Meeting; +import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpert; +import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; +import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatusEnum; +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.meeting.task.ExpertInviteTask; +import com.ningdatech.pmapi.sms.utils.DateUtil; +import com.ningdatech.pmapi.user.service.IUserInfoService; +import com.ningdatech.pmapi.user.util.LoginUserUtil; +import lombok.AllArgsConstructor; +import org.springframework.aop.framework.AopContext; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + + +/** + *

+ * LeaveManage + *

+ * + * @author WendyYang + * @since 10:38 2022/8/11 + */ +@Component +@AllArgsConstructor +public class LeaveManage { + + private final ExpertInviteTask inviteTask; + private final IMeetingService meetingService; + private final IMeetingExpertService meetingExpertService; + private final IExpertLeaveService leaveService; + private final IExpertLeaveDetailService leaveDetailService; + private final IExpertMetaApplyService metaApplyService; + private final FileService fileService; + private final IExpertUserFullInfoService userFullInfoService; + private final YxtCallOrSmsHelper yxtCallOrSmsHelper; + private final IUserInfoService userInfoService; + + private static final int HOURS_BEFORE_MEETING = 12; + + public void cancelMeetingExpertByLeave(Long meetingExpertId, ExpertAttendStatusEnum status) { + MeetingExpert update = buildMeetingExpertUpdate(meetingExpertId, status); + meetingExpertService.updateById(update); + } + + private MeetingExpert buildMeetingExpertUpdate(Long meetingExpertId, ExpertAttendStatusEnum status) { + MeetingExpert expert = new MeetingExpert(); + expert.setId(meetingExpertId); + expert.setStatus(status.getCode()); + return expert; + } + + private List listMeetingExpert(Long expertId, List> leaveTimes) { + // 先查询专家参与的所有会议 + LambdaQueryWrapper meetingExpertQuery = Wrappers.lambdaQuery(MeetingExpert.class) + .eq(MeetingExpert::getExpertId, expertId) + .in(MeetingExpert::getStatus, Arrays.asList(ExpertAttendStatusEnum.NOTICING.getCode(), + ExpertAttendStatusEnum.AGREED.getCode())); + List meetingExperts = meetingExpertService.list(meetingExpertQuery); + if (meetingExperts.isEmpty()) { + return Collections.emptyList(); + } + // 只需要查询待确认的或者是同意参加的 + Map expertMap = meetingExperts.stream() + .collect(Collectors.groupingBy(MeetingExpert::getMeetingId, + Collectors.collectingAndThen(Collectors.toList(), w -> { + w.sort(Comparator.comparing(MeetingExpert::getUpdateOn).reversed()); + return w.get(0); + }))); + List meetingIds = CollUtils.fieldList(expertMap.values(), MeetingExpert::getMeetingId); + LocalDateTime startTime = leaveTimes.get(0).getKey(), endTime = leaveTimes.get(leaveTimes.size() - 1).getValue(); + LambdaQueryWrapper meetingQuery = Wrappers.lambdaQuery(Meeting.class) + .in(Meeting::getId, meetingIds) + .ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode()) + .and(w -> w.between(Meeting::getStartTime, startTime, endTime) + .or(or -> or.between(Meeting::getEndTime, startTime, endTime))); + List meetingList = meetingService.list(meetingQuery); + List matchMeetingIds = meetingList.stream() + .filter(w -> leaveTimes.stream() + .anyMatch(tp -> DateUtil.intersect(w.getStartTime(), w.getEndTime(), tp.getKey(), tp.getValue()))) + .map(Meeting::getId).collect(Collectors.toList()); + if (matchMeetingIds.isEmpty()) { + return Collections.emptyList(); + } + return matchMeetingIds.stream().map(expertMap::get).collect(Collectors.toList()); + } + + @Transactional(rollbackFor = Exception.class) + public IdVo askForLeave(LeaveCreateReq po) { + Long leaveUserId, applyUserId = Objects.requireNonNull(LoginUserUtil.getUserId()); + leaveUserId = po.getExpertId() != null ? po.getExpertId() : applyUserId; + boolean leaveForSelf = leaveUserId.equals(applyUserId); + if (!leaveForSelf) { + Assert.isFalse(leaveService.existsToBeReviewed(leaveUserId), "该专家存在待审核请假申请,请及时审核"); + } + LeaveTypeEnum type = LeaveTypeEnum.getByCode(po.getType()); + // 校验参数是否合法 + po.paramCheck(type); + ExpertLeave leave = new ExpertLeave(); + if (po.getAttachments() != null) { + leave.setAttachment(CollUtils.joinByComma(po.getAttachments())); + } + LocalDateTime now = LocalDateTime.now(); + leave.setType(po.getType()); + leave.setRemark(po.getPostscript()); + leave.setLeaveUserId(leaveUserId); + leave.setUpdateAndCreate(applyUserId, now); + List> leaveDetailTimes = new ArrayList<>(); + if (type.equals(LeaveTypeEnum.FIXED_TERM) || type.equals(LeaveTypeEnum.LONG_TERM)) { + boolean fixedTerm = CollUtil.isNotEmpty(po.getFixedType()); + if (fixedTerm) { + // 固定时段请假 + leave.setFixedType(CollUtils.joinByComma(po.getFixedType())); + } + LocalDateTime tempStart = po.getStartTime(); + while (!tempStart.isAfter(po.getEndTime())) { + boolean add = true; + if (fixedTerm) { + int weekday = tempStart.getDayOfWeek().getValue(); + add = po.getFixedType().contains(weekday); + } + if (add) { + LocalDateTime tempEnd = tempStart.toLocalDate().atTime(DateUtil.LOCAL_TIME_3D); + leaveDetailTimes.add(KeyValDTO.of(tempStart, DateUtil.min(tempEnd, po.getEndTime()))); + } + tempStart = tempStart.plusDays(1).toLocalDate().atStartOfDay(); + } + if (leaveDetailTimes.isEmpty()) { + throw BizException.wrap("请假时间无效"); + } + if (leaveDetailService.existsLeaveByUserIdAndTime(leaveUserId, leaveDetailTimes)) { + throw BizException.wrap("该请假时段内已存在请假"); + } + List meetingExperts = listMeetingExpert(leaveUserId, leaveDetailTimes); + if (!meetingExperts.isEmpty()) { + if (meetingExperts.stream().anyMatch(w -> ExpertAttendStatusEnum.AGREED.eq(w.getStatus()))) { + throw BizException.wrap("有待参加会议,请先处理完会议,再发起请假"); + } + List expertsUpdate = meetingExperts.stream() + .map(w -> buildMeetingExpertUpdate(w.getExpertId(), ExpertAttendStatusEnum.ON_LEAVE)) + .collect(Collectors.toList()); + meetingExpertService.updateBatchById(expertsUpdate); + } + leave.setStatus(LeaveStatusEnum.APPLYING.getCode()); + } else if (type.equals(LeaveTypeEnum.TEMPORARY)) { + // 临时请假 + Meeting meeting = meetingService.getById(po.getMeetingId()); + if (meeting.getStatus().equals(MeetingStatusEnum.CANCELED.getCode())) { + throw BizException.wrap("该会议已取消"); + } + po.setStartTime(meeting.getStartTime()); + po.setEndTime(meeting.getEndTime()); + if (now.plusHours(HOURS_BEFORE_MEETING).isAfter(po.getStartTime())) { + throw BizException.wrap("会议临期" + HOURS_BEFORE_MEETING + "小时内,不能在线请假,请电话该主题事务的联系人。"); + } + MeetingExpert expert = meetingExpertService.getByMeetingIdAndExpertId(po.getMeetingId(), leaveUserId); + if (!expert.getStatus().equals(ExpertAttendStatusEnum.AGREED.getCode())) { + // 非确认参加状态无法临时请假 + throw BizException.wrap("未同意参加该会议,无法临时请假"); + } + LocalDateTime tempStart = po.getStartTime(); + while (!tempStart.isAfter(po.getEndTime())) { + LocalDateTime tempEnd = tempStart.toLocalDate().atTime(DateUtil.LOCAL_TIME_3D); + leaveDetailTimes.add(KeyValDTO.of(tempStart, DateUtil.min(tempEnd, po.getEndTime()))); + tempStart = tempStart.plusDays(1).toLocalDate().atStartOfDay(); + } + LeaveManage proxy = (LeaveManage) AopContext.currentProxy(); + proxy.cancelMeetingExpertByLeave(expert.getId(), ExpertAttendStatusEnum.ON_LEAVE); + inviteTask.notifyInviteTask(meeting.getId(), Boolean.FALSE); + // 临时请假无需审核 + leave.setAuditId(0L); + leave.setStatus(LeaveStatusEnum.PASSED.getCode()); + // 临时请假需通知专家管理进行专家补抽 + } + if (type != LeaveTypeEnum.TEMPORARY) { + ExpertMetaApply apply = getExpertMetaApply(po, leaveUserId, applyUserId, now); + leave.setAuditId(apply.getId()); + if (!leaveForSelf) { + leave.setStatus(LeaveStatusEnum.PASSED.getCode()); + } + } + leave.setStartTime(po.getStartTime()); + leave.setEndTime(po.getEndTime()); + leave.setCancelTime(po.getEndTime()); + leaveService.save(leave); + List detailList = CollUtils.convert(leaveDetailTimes, w -> new ExpertLeaveDetail(leave.getId(), w.getKey(), w.getValue())); + leaveDetailService.saveBatch(detailList); + return IdVo.of(leave.getId()); + } + + private ExpertMetaApply getExpertMetaApply(LeaveCreateReq po, Long leaveUserId, Long applyUserId, LocalDateTime now) { + // 非临时请假需要审批 + ExpertMetaApply apply = new ExpertMetaApply(); + apply.setCreateOn(now); + apply.setUpdateOn(now); + apply.setApplyType(ExpertApplyTypeEnum.LONG_TERM_LEAVE.getKey()); + if (applyUserId.equals(leaveUserId)) { + apply.setApplyStatus(ExpertApplyStatusEnum.PENDING_REVIEW.getKey()); + } else { + // 专家管理员发起请假自动通过 + apply.setReviewTime(now); + apply.setApprover(LoginUserUtil.getUsername()); + apply.setApproverUserId(applyUserId); + apply.setApplyStatus(ExpertApplyStatusEnum.PASSED.getKey()); + } + apply.setUserId(leaveUserId); + apply.setApplicantId(applyUserId); + ExpertUserFullInfo userInfo = userFullInfoService.getByUserId(apply.getUserId()); + apply.setRegionCode(userInfo.getRegionCode()); + apply.setRegionLevel(userInfo.getRegionLevel()); + ModifyApplyExtraInfoDTO extraInfo = new ModifyApplyExtraInfoDTO(); + extraInfo.setFactSheet(po.getPostscript()); + if (po.getAttachments() != null) { + List infoList = CollUtils.convert(po.getAttachments(), w -> { + FileBasicInfo info = new FileBasicInfo(); + info.setFileId(w); + return info; + }); + extraInfo.setEvidenceList(infoList); + } + apply.setExtraMaterial(JSONUtil.toJsonStr(extraInfo)); + metaApplyService.save(apply); + return apply; + } + + public PageVo leaveListByCreator(LeaveListByCreatorReq po) { + if (po.getExpertId() == null) { + po.setExpertId(LoginUserUtil.getUserId()); + } + LambdaQueryWrapper query = Wrappers.lambdaQuery(ExpertLeave.class) + .orderByDesc(ExpertLeave::getCreateOn); + if (po.getLeaveType() != null && po.getLeaveType().equals(LeaveTypeEnum.TEMPORARY.getCode())) { + // 临时请假 + if (po.getAuditStatus() != null && !po.getAuditStatus().equals(ExpertApplyStatusEnum.PASSED.getKey())) { + return PageVo.empty(); + } + query.eq(ExpertLeave::getAuditId, 0L); + query.eq(ExpertLeave::getLeaveUserId, po.getExpertId()); + } else { + if (StrUtils.isNotBlank(po.getAuditStatus())) { + LambdaQueryWrapper queryApply = Wrappers.lambdaQuery(ExpertMetaApply.class) + .select(ExpertMetaApply::getId) + .eq(ExpertMetaApply::getUserId, po.getExpertId()) + .eq(ExpertMetaApply::getApplyStatus, po.getAuditStatus()); + List applyList = metaApplyService.list(queryApply); + List auditIds = CollUtils.fieldList(applyList, ExpertMetaApply::getId); + if (po.getAuditStatus().equals(ExpertApplyStatusEnum.PASSED.getKey())) { + query.eq(ExpertLeave::getLeaveUserId, po.getExpertId()); + auditIds.add(0L); + } + if (auditIds.isEmpty()) { + return PageVo.empty(); + } + query.in(ExpertLeave::getAuditId, auditIds); + } else { + query.eq(ExpertLeave::getLeaveUserId, po.getExpertId()); + } + query.eq(po.getLeaveType() != null, ExpertLeave::getType, po.getLeaveType()); + } + if (po.getStartTime() != null && po.getEndTime() != null) { + query.and(wrapper -> wrapper.between(ExpertLeave::getStartTime, po.getStartTime(), po.getEndTime()) + .or(or -> or.between(ExpertLeave::getEndTime, po.getStartTime(), po.getEndTime()))); + } + Page page = leaveService.page(po.page(), query); + if (page.getTotal() == 0) { + return PageVo.empty(); + } + List meetingIds = new ArrayList<>(), auditIds = new ArrayList<>(), fileIds = new ArrayList<>(); + page.getRecords().forEach(w -> { + if (w.getMeetingId() != 0) { + meetingIds.add(w.getMeetingId()); + } + if (w.getAuditId() != 0) { + auditIds.add(w.getAuditId()); + } + if (!w.getAttachment().isEmpty()) { + List tempFileIds = BizUtils.splitToLong(w.getAttachment()); + fileIds.addAll(tempFileIds); + } + }); + Map meetingMap = new HashMap<>(16); + if (!meetingIds.isEmpty()) { + meetingMap.putAll(CollUtils.listToMap(meetingService.listByIds(meetingIds), Meeting::getId)); + } + Map applyMap = new HashMap<>(16); + if (!auditIds.isEmpty()) { + applyMap.putAll(CollUtils.listToMap(metaApplyService.listByIds(auditIds), ExpertMetaApply::getId)); + } + Map fileMap = new HashMap<>(fileIds.size()); + if (!fileIds.isEmpty()) { + fileMap.putAll(CollUtils.listToMap(fileService.getByIds(fileIds), AttachFileVo::getFileId)); + } + List dataList = CollUtils.convert(page.getRecords(), w -> { + LeaveListItemVO item = new LeaveListItemVO(); + item.setLeaveType(w.getType()); + item.setPostscript(w.getRemark()); + item.setAuditId(w.getAuditId()); + item.setLeaveId(w.getId()); + item.setStartTime(w.getStartTime()); + item.setEndTime(w.getEndTime()); + ExpertMetaApply apply = applyMap.get(w.getAuditId()); + item.setAuditOption(apply != null ? apply.getAuditOpinion() : StrUtil.EMPTY); + item.setStatus(w.getStatus()); + item.setAuditStatus(apply != null ? apply.getApplyStatus() : ExpertApplyStatusEnum.PASSED.getKey()); + item.setActualEndTime(w.getCancelTime()); + Meeting meeting = meetingMap.get(w.getMeetingId()); + item.setMeetingName(meeting != null ? meeting.getName() : StrUtil.EMPTY); + item.setAttachments(new ArrayList<>()); + if (!w.getAttachment().isEmpty()) { + Arrays.stream(w.getAttachment().split(",")).forEach(fileId -> item.getAttachments().add(fileMap.get(Long.parseLong(fileId)))); + } + return item; + }); + return PageVo.of(dataList, page.getTotal()); + } + + public void endLeave(Long leaveId) { + ExpertLeave leave = leaveService.getById(leaveId); + if (LeaveTypeEnum.TEMPORARY.eq(leave.getType())) { + throw BizException.wrap("临时请假不支持销假"); + } + LeaveStatusEnum status = LeaveStatusEnum.getByCode(leave.getStatus()); + if (!status.equals(LeaveStatusEnum.PASSED) || LocalDateTime.now().isAfter(leave.getEndTime())) { + throw BizException.wrap("该请假不支持销假"); + } + LocalDateTime actualEndTime = LocalDateTime.now(); + LambdaUpdateWrapper updater = Wrappers.lambdaUpdate(ExpertLeave.class) + .set(ExpertLeave::getCancelTime, actualEndTime) + .set(ExpertLeave::getUpdateOn, actualEndTime) + .set(ExpertLeave::getUpdateBy, LoginUserUtil.getUserId()) + .set(ExpertLeave::getStatus, LeaveStatusEnum.PASSED_END.getCode()) + .eq(ExpertLeave::getId, leave.getId()); + leaveService.update(updater); + LambdaQueryWrapper deleter = Wrappers.lambdaQuery(ExpertLeaveDetail.class) + .ge(ExpertLeaveDetail::getStartTime, actualEndTime.toLocalDate()) + .eq(ExpertLeaveDetail::getExpertLeaveId, leaveId); + leaveDetailService.remove(deleter); + } + + public void cancel(Long leaveId) { + ExpertLeave leave = leaveService.getById(leaveId); + if (LeaveTypeEnum.TEMPORARY.eq(leave.getType())) { + throw BizException.wrap("临时请假不支持撤销"); + } + if (LeaveStatusEnum.APPLYING.eq(leave.getStatus())) { + throw BizException.wrap("该请假不支持撤销"); + } + LocalDateTime actualEndTime = LocalDateTime.now(); + // 修改请假状态 + LambdaUpdateWrapper updater = Wrappers.lambdaUpdate(ExpertLeave.class) + .set(ExpertLeave::getUpdateOn, actualEndTime) + .set(ExpertLeave::getUpdateBy, LoginUserUtil.getUserId()) + .set(ExpertLeave::getStatus, LeaveStatusEnum.CANCELED.getCode()) + .eq(ExpertLeave::getId, leave.getId()); + leaveService.update(updater); + // 删除请假详情 + LambdaQueryWrapper deleter = Wrappers.lambdaQuery(ExpertLeaveDetail.class) + .eq(ExpertLeaveDetail::getExpertLeaveId, leaveId); + leaveDetailService.remove(deleter); + // 修改审核表 + LambdaUpdateWrapper updaterApply = Wrappers.lambdaUpdate(ExpertMetaApply.class) + .set(ExpertMetaApply::getApplyStatus, ExpertApplyStatusEnum.REVOKED.getKey()) + .set(ExpertMetaApply::getUpdateOn, LocalDateTime.now()) + .set(ExpertMetaApply::getAuditOpinion, "发起人撤销") + .eq(ExpertMetaApply::getId, leave.getAuditId()); + metaApplyService.update(updaterApply); + } + + public LeaveDetailVO leaveDetail(Long leaveId, Long auditId) { + ExpertLeave leave; + if (leaveId != null) { + leave = leaveService.getById(leaveId); + } else { + leave = leaveService.getByAuditId(auditId); + } + LeaveDetailVO detail = LeaveDetailVO.builder() + .createOn(leave.getCreateOn()) + .createBy(leave.getCreator()) + .postscript(leave.getRemark()) + .id(leave.getId()) + .status(leave.getStatus()) + .startTime(leave.getStartTime()) + .endTime(leave.getEndTime()) + .attachments(new ArrayList<>()) + .type(leave.getType()) + .actualEndTime(leave.getCancelTime()) + .auditId(leave.getAuditId()) + .build(); + if (LeaveTypeEnum.FIXED_TERM.eq(leave.getType())) { + detail.setFixedType(BizUtils.splitToNum(leave.getFixedType(), Integer.class)); + } + if (StrUtils.isNotBlank(leave.getAttachment())) { + List fileIds = BizUtils.splitToLong(leave.getAttachment()); + List files = fileService.getByIds(fileIds); + detail.getAttachments().addAll(files); + } + return detail; + } + + public List listLeaveUserIdByTime(LocalDateTime start, LocalDateTime end) { + LambdaQueryWrapper leaveDetailQuery = Wrappers.lambdaQuery(ExpertLeaveDetail.class) + .select(ExpertLeaveDetail::getExpertLeaveId) + .and(wrapper -> wrapper.between(ExpertLeaveDetail::getStartTime, start, end) + .or(wrapper1 -> wrapper1.between(ExpertLeaveDetail::getEndTime, start, end))); + List detailList = leaveDetailService.list(leaveDetailQuery); + if (detailList.isEmpty()) { + return new ArrayList<>(); + } + List leaveIdList = CollUtils.fieldList(detailList, ExpertLeaveDetail::getExpertLeaveId); + LambdaQueryWrapper leaveQuery = Wrappers.lambdaQuery(ExpertLeave.class) + .select(ExpertLeave::getCreateBy) + .in(ExpertLeave::getId, leaveIdList) + .in(ExpertLeave::getStatus, + LeaveStatusEnum.APPLYING.getCode(), + LeaveStatusEnum.PASSED.getCode(), + LeaveStatusEnum.PASSED_END.getCode()); + List leaveList = leaveService.list(leaveQuery); + return CollUtils.fieldList(leaveList, ExpertLeave::getCreateBy); + } + + @Transactional(rollbackFor = Exception.class) + public void leaveAuditCallback(boolean status, Long applyId) { + LambdaUpdateWrapper update = Wrappers.lambdaUpdate(ExpertLeave.class) + .set(ExpertLeave::getUpdateBy, LoginUserUtil.getUserId()) + .set(ExpertLeave::getUpdateOn, LocalDateTime.now()) + .eq(ExpertLeave::getAuditId, applyId); + ExpertLeave leave = leaveService.getByAuditId(applyId); + ExpertUserFullInfo leaveUser = userFullInfoService.getByUserId(leave.getLeaveUserId()); + if (status) { + update.set(ExpertLeave::getStatus, LeaveStatusEnum.PASSED.getCode()); + } else { + ExpertMetaApply metaApply = metaApplyService.getById(applyId); + update.set(ExpertLeave::getStatus, LeaveStatusEnum.UN_PASSED.getCode()); + LambdaQueryWrapper delete = Wrappers.lambdaQuery(ExpertLeaveDetail.class) + .eq(ExpertLeaveDetail::getExpertLeaveId, leave.getId()); + leaveDetailService.remove(delete); + } + leaveService.update(update); + } + + public Map> listLeaveIdByDate(LocalDate startDate, LocalDate endDate, Long expertId) { + List leaveDetails = leaveDetailService.listByDateAndLeaveUserId(startDate, endDate, expertId); + return leaveDetails.stream().collect(Collectors.groupingBy(w -> w.getStartTime().toLocalDate(), + Collectors.mapping(ExpertLeaveDetail::getExpertLeaveId, Collectors.toSet()))); + } + + public PageVo listLeaveApplyingAndCouldBeStop(PagePo po) { + LambdaQueryWrapper query = Wrappers.lambdaQuery(ExpertLeave.class) + .eq(ExpertLeave::getLeaveUserId, LoginUserUtil.getUserId()) + .and(wrapper -> wrapper.eq(ExpertLeave::getStatus, LeaveStatusEnum.APPLYING.getCode()) + .or(wrapper1 -> wrapper1.eq(ExpertLeave::getStatus, LeaveStatusEnum.PASSED.getCode()) + .gt(ExpertLeave::getCancelTime, LocalDateTime.now()))); + Page page = leaveService.page(new Page<>(po.getPageNumber(), po.getPageSize()), query); + if (page.getTotal() == 0) { + return PageVo.empty(); + } + List result = CollUtils.convert(page.getRecords(), w -> { + LeaveListItemVO item = new LeaveListItemVO(); + item.setStartTime(w.getStartTime()); + item.setEndTime(w.getEndTime()); + item.setStatus(w.getStatus()); + item.setLeaveType(w.getType()); + item.setLeaveId(w.getId()); + return item; + }); + return PageVo.of(result, page.getTotal()); + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveDetailMapper.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveDetailMapper.java new file mode 100644 index 0000000..7e86713 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveDetailMapper.java @@ -0,0 +1,46 @@ +package com.ningdatech.pmapi.leave.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ningdatech.pmapi.common.model.entity.KeyValDTO; +import com.ningdatech.pmapi.leave.entity.domain.ExpertLeaveDetail; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 专家请假详情表(维度:天) Mapper 接口 + *

+ * + * @author WendyYang + * @since 2022-08-11 + */ +public interface ExpertLeaveDetailMapper extends BaseMapper { + + /** + * 查询时间段之内的请假信息(请假状态:已通过、销假) + * + * @param leaveUserId 请假人ID + * @param startDate 开始时间 + * @param endDate 结束时间 + * @return 请假详情 + * @author WendyYang + **/ + List selectLeaveIdByDateAndExpertId(@Param("leaveUserId") Long leaveUserId, + @Param("startDate") LocalDate startDate, + @Param("endDate") LocalDate endDate); + + /** + * 查询用户在指定时间之内是否有请假 + * + * @param leaveUserId 用户ID + * @param times 时间集合 + * @return 请假天数 + * @author WendyYang + **/ + Integer existsLeaveByLeaveUserIdAndTime(@Param("leaveUserId") Long leaveUserId, + @Param("times") List> times); + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveDetailMapper.xml b/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveDetailMapper.xml new file mode 100644 index 0000000..4d5b63e --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveDetailMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveMapper.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveMapper.java new file mode 100644 index 0000000..4b78046 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveMapper.java @@ -0,0 +1,16 @@ +package com.ningdatech.pmapi.leave.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ningdatech.pmapi.leave.entity.domain.ExpertLeave; + +/** + *

+ * Mapper 接口 + *

+ * + * @author WendyYang + * @since 2022-08-11 + */ +public interface ExpertLeaveMapper extends BaseMapper { + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveMapper.xml b/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveMapper.xml new file mode 100644 index 0000000..c95f146 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/mapper/ExpertLeaveMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/IExpertLeaveDetailService.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/IExpertLeaveDetailService.java new file mode 100644 index 0000000..b1df329 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/IExpertLeaveDetailService.java @@ -0,0 +1,25 @@ +package com.ningdatech.pmapi.leave.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ningdatech.pmapi.common.model.entity.KeyValDTO; +import com.ningdatech.pmapi.leave.entity.domain.ExpertLeaveDetail; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 专家请假详情表(维度:天) 服务类 + *

+ * + * @author WendyYang + * @since 2022-08-11 + */ +public interface IExpertLeaveDetailService extends IService { + + List listByDateAndLeaveUserId(LocalDate startDate, LocalDate endDate, Long leaveUserId); + + boolean existsLeaveByUserIdAndTime(Long userId, List> times); + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/IExpertLeaveService.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/IExpertLeaveService.java new file mode 100644 index 0000000..f54512c --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/IExpertLeaveService.java @@ -0,0 +1,26 @@ +package com.ningdatech.pmapi.leave.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ningdatech.pmapi.leave.entity.domain.ExpertLeave; + +/** + *

+ * 服务类 + *

+ * + * @author WendyYang + * @since 2022-08-11 + */ +public interface IExpertLeaveService extends IService { + + ExpertLeave getByAuditId(Long auditId); + + /** + * 是否存在待审核请假记录 + * + * @param expertId 专家ID + * @return boolean + */ + boolean existsToBeReviewed(Long expertId); + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/impl/ExpertLeaveDetailServiceImpl.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/impl/ExpertLeaveDetailServiceImpl.java new file mode 100644 index 0000000..937100f --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/impl/ExpertLeaveDetailServiceImpl.java @@ -0,0 +1,35 @@ +package com.ningdatech.pmapi.leave.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ningdatech.pmapi.common.model.entity.KeyValDTO; +import com.ningdatech.pmapi.leave.entity.domain.ExpertLeaveDetail; +import com.ningdatech.pmapi.leave.mapper.ExpertLeaveDetailMapper; +import com.ningdatech.pmapi.leave.service.IExpertLeaveDetailService; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 专家请假详情表(维度:天) 服务实现类 + *

+ * + * @author WendyYang + * @since 2022-08-11 + */ +@Service +public class ExpertLeaveDetailServiceImpl extends ServiceImpl implements IExpertLeaveDetailService { + + @Override + public List listByDateAndLeaveUserId(LocalDate startDate, LocalDate endDate, Long leaveUserId) { + return baseMapper.selectLeaveIdByDateAndExpertId(leaveUserId, startDate, endDate.plusDays(1)); + } + + @Override + public boolean existsLeaveByUserIdAndTime(Long userId, List> times) { + return baseMapper.existsLeaveByLeaveUserIdAndTime(userId, times) != null; + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/impl/ExpertLeaveServiceImpl.java b/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/impl/ExpertLeaveServiceImpl.java new file mode 100644 index 0000000..dda0f17 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/leave/service/impl/ExpertLeaveServiceImpl.java @@ -0,0 +1,41 @@ +package com.ningdatech.pmapi.leave.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ningdatech.pmapi.leave.entity.domain.ExpertLeave; +import com.ningdatech.pmapi.leave.entity.enumeration.LeaveStatusEnum; +import com.ningdatech.pmapi.leave.mapper.ExpertLeaveMapper; +import com.ningdatech.pmapi.leave.service.IExpertLeaveService; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author WendyYang + * @since 2022-08-11 + */ +@Service +public class ExpertLeaveServiceImpl extends ServiceImpl implements IExpertLeaveService { + + @Override + public ExpertLeave getByAuditId(Long auditId) { + if (auditId == 0) { + return null; + } + LambdaQueryWrapper query = Wrappers.lambdaQuery(ExpertLeave.class) + .eq(ExpertLeave::getAuditId, auditId); + return getOne(query); + } + + @Override + public boolean existsToBeReviewed(Long expertId) { + LambdaQueryWrapper query = Wrappers.lambdaQuery(ExpertLeave.class) + .eq(ExpertLeave::getLeaveUserId, expertId) + .eq(ExpertLeave::getStatus, LeaveStatusEnum.APPLYING.getCode()); + return baseMapper.exists(query); + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/enumeration/ExpertAttendStatusEnum.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/enumeration/ExpertAttendStatusEnum.java index 7f34237..a0f8746 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/enumeration/ExpertAttendStatusEnum.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/enumeration/ExpertAttendStatusEnum.java @@ -21,6 +21,7 @@ public enum ExpertAttendStatusEnum { UNANSWERED("未应答", 1), AGREED("同意参加", 3), REFUSED("拒绝参加", 4), + ON_LEAVE("已请假", 5), RELEASED("已释放", 7); private final String value; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/MeetingListReq.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/MeetingListReq.java index 7375f3a..2d206dd 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/MeetingListReq.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/req/MeetingListReq.java @@ -33,8 +33,7 @@ public class MeetingListReq extends PagePo { @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime endTime; - @ApiModelProperty("事务状态:1 未完成、2 已完成、3 已取消\n" + - "专家参与状态:1 待参加、2 已参加、3 已请假") + @ApiModelProperty("事务状态") private Integer status; @ApiModelProperty("会议类型") diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/vo/MeetingByManagerVO.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/vo/MeetingByManagerVO.java index 2997259..a906367 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/vo/MeetingByManagerVO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/vo/MeetingByManagerVO.java @@ -49,9 +49,6 @@ public class MeetingByManagerVO { @ApiModelProperty("名单确认状态") private Boolean confirmedRoster; - @ApiModelProperty("会议参加状态:1 待参加、2 已参加、3 已请假") - private Integer attendStatus; - @ApiModelProperty("会议名称") private String meetingName; @@ -61,4 +58,7 @@ public class MeetingByManagerVO { @ApiModelProperty("会议类型名称") private String meetingTypeName; + @ApiModelProperty("专家状态") + private Integer expertStatus; + } 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 3a02ad2..30f61d5 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 @@ -284,15 +284,16 @@ public class MeetingManage { **/ public PageVo meetingListByExpert(MeetingListReq req) { Long expertId = req.getExpertId() != null ? req.getExpertId() : LoginUserUtil.getUserId(); - List expertDtoList = meetingExpertService.listByExpertIdAndStatus(expertId, req.getStatus(), null); - if (expertDtoList.isEmpty()) { + List meetings = meetingExpertService.listByExpertIdAndStatus(expertId, null, null); + if (meetings.isEmpty()) { return PageVo.empty(); } Map mapByMeetingId = new HashMap<>(16); - expertDtoList.forEach(w -> mapByMeetingId.put(w.getMeetingId(), w)); + meetings.forEach(w -> mapByMeetingId.put(w.getMeetingId(), w)); LambdaQueryWrapper query = new LambdaQueryWrapper() .orderByDesc(Meeting::getCreateOn) .in(Meeting::getId, mapByMeetingId.keySet()) + .eq(Meeting::getConfirmedRoster, Boolean.TRUE) .ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode()); if (req.getExpertId() == null) { meetingManageHelper.buildMeetingQuery(query, req); @@ -305,7 +306,7 @@ public class MeetingManage { page.getRecords().forEach(meeting -> { MeetingByManagerVO item = meetingManageHelper.buildByMeeting(meeting); MeetingAndAttendStatusDTO info = mapByMeetingId.get(meeting.getId()); - item.setAttendStatus(meetingManageHelper.getExpertAttendStatus(info)); + item.setExpertStatus(info.getStatus()); result.getRecords().add(item); }); return result; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/task/ExpertInviteTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/task/ExpertInviteTask.java index 3caf61b..f58915e 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/task/ExpertInviteTask.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/task/ExpertInviteTask.java @@ -1,5 +1,6 @@ package com.ningdatech.pmapi.meeting.task; +import cn.hutool.core.util.ArrayUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -21,7 +22,6 @@ import com.ningdatech.pmapi.meeting.service.IExpertInviteAvoidRuleService; 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.user.util.LoginUserUtil; import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; @@ -146,18 +146,23 @@ public class ExpertInviteTask { /** * 唤醒某个会议的抽取任务 * - * @param meetingId 会议ID + * @param meetingId 会议ID + * @param invitedRefused 是否可邀请已拒绝的专家 * @author WendyYang **/ - public void notifyInviteTask(Long meetingId) { + public void notifyInviteTask(Long meetingId, boolean... invitedRefused) { + boolean tmpInvitedRefused = true; + if (ArrayUtil.isNotEmpty(invitedRefused)) { + tmpInvitedRefused = invitedRefused[0]; + } if (!INVITE_MAP.containsKey(meetingId)) { - addInviteExpertTask(meetingId, false, properties.getInviteDelay(), true); + addInviteExpertTask(meetingId, false, properties.getInviteDelay(), tmpInvitedRefused); log.info("重置会议的随机抽取状态:{}", meetingId); LambdaUpdateWrapper update = Wrappers.lambdaUpdate(Meeting.class); update.set(Meeting::getInviteStatus, false); update.eq(Meeting::getId, meetingId); meetingService.update(update); - InviteCacheDTO cacheVal = InviteCacheDTO.of(meetingId, true); + InviteCacheDTO cacheVal = InviteCacheDTO.of(meetingId, tmpInvitedRefused); cachePlusOps.hSet(getCacheKey(meetingId), cacheVal); } } @@ -252,11 +257,7 @@ public class ExpertInviteTask { }); if (notIgnoreCnt.get() == 0 || notIgnoreCnt.get() == notSupportCnt.get()) { if (notSupportCnt.get() > 0) { - // TODO - /*UserInfo inviterBasic = userInfoService.getById(meeting.getCreateBy()); - UserInfo inviter = userInfoService.getById(inviterBasic.getId()); - SendSmsContext context = YxtSmsContextBuilder.smsByRandomInviteStop(inviter.getNickname(), meeting.getName(), inviterBasic.getPhoneNo()); - yxtCallOrSmsHelper.sendSms(context);*/ + // TODO 发送邀请停止短信 } log.info("停止会议随机邀请:{} 未完成抽取规则数量 {} 无可抽取专家规则数量 {}", meetingId, notIgnoreCnt, notSupportCnt); currProxy().cancelByMeetingId(meetingId); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/DeclaredProjectController.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/DeclaredProjectController.java index 3881b56..bf99653 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/DeclaredProjectController.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/DeclaredProjectController.java @@ -1,13 +1,11 @@ package com.ningdatech.pmapi.projectdeclared.controller; import com.ningdatech.basic.model.PageVo; -import com.ningdatech.pmapi.projectdeclared.manage.DefaultDeclaredProjectManage; import com.ningdatech.pmapi.projectdeclared.model.dto.DeclaredProjectListParamDTO; import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectDraftSaveDTO; import com.ningdatech.pmapi.projectdeclared.model.vo.ProjectDraftVO; import com.ningdatech.pmapi.projectdeclared.manage.DeclaredProjectManage; -import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; import io.swagger.annotations.Api; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java index 2bf9ab0..900a988 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java @@ -117,8 +117,8 @@ public class ConstructionPlanManage { }) ); params.setFormData(dto.getFormData()); - // 获取发起单位、发起单位主管单位信息 - Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId, model); + // 获取发起单位、发起单位主管单位、发起单位上级条线主管单位信息 + Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId); String instanceId = processService.newStartProcess(model.getProcessDefId(),model.getFormId(), params,orgModelMap); log.info("建设方案项目申报成功 【{}】", instanceId); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java index 47b456a..bd5c3bc 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java @@ -143,8 +143,8 @@ public class DeclaredProjectManage { ); params.setFormData(dto.getFormData()); //开始申报 - // 获取发起单位、发起单位主管单位流程信息map - Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId, model); + // 获取发起单位、发起单位主管单位、发起单位上级主管条线单位信息 + Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId); String instanceId = processService.newStartProcess(model.getProcessDefId(),model.getFormId(), params,orgModelMap); log.info("申报项目成功 【{}】", instanceId); @@ -207,8 +207,8 @@ public class DeclaredProjectManage { }) ); params.setFormData(dto.getFormData()); - // 获取发起单位、发起单位主管单位流程信息map - Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId, model); + // 获取发起单位、发起单位主管单位、发起单位上级主管条线单位信息 + Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId); String instanceId = processService.newStartProcess(model.getProcessDefId(),model.getFormId(), params,orgModelMap); log.info("重新申报项目成功 【{}】", instanceId); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DefaultDeclaredProjectManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DefaultDeclaredProjectManage.java index 7842f1f..0754d51 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DefaultDeclaredProjectManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DefaultDeclaredProjectManage.java @@ -67,7 +67,7 @@ public class DefaultDeclaredProjectManage { .build(); } - public Map getOrgModelInfo(Long userId, WflowModels model) { + public Map getOrgModelInfo(Long userId) { Map orgMap = new HashMap<>(); // 查出所有的单位流程配置 @@ -78,8 +78,16 @@ public class DefaultDeclaredProjectManage { .eq(DingOrganization::getOrganizationCode, userFullInfo.getOrganizationCode())); String startOrgCode = startOrg.getOrganizationCode(); String startOrgName = startOrg.getOrganizationName(); - String startOrgParentCode = startOrg.getParentCode(); - String startOrgParentName = startOrg.getParentName(); + String startOrgParentCode; + String startOrgParentName; + // 如果没有上级主管单位,由该单位自己审核 + if (Objects.isNull(startOrg.getParentCode())){ + startOrgParentCode = startOrgCode; + startOrgParentName = startOrgName; + }else { + startOrgParentCode = startOrg.getParentCode(); + startOrgParentName = startOrg.getParentName(); + } //查询 当前发起人及主管单位所在区域的 单位流程配置 OrgInfoDTO startOrgInfoDto = new OrgInfoDTO(); startOrgInfoDto.setOrganizationCode(startOrgCode); @@ -105,6 +113,8 @@ public class DefaultDeclaredProjectManage { orgMap.put(OrgTypeEnum.TARGET_OWNER.name(),startOrgInfoDto); orgMap.put(OrgTypeEnum.TARGET_MANAGEMENT.name(),parentOrgInfoDto); + // TODO 上级条线主管单位信息(可能是多个) + // 如果是指定单位,直接根据流程定义ID放入map OrgInfoDTO orgInfoDTO = new OrgInfoDTO(); orgInfoDTO.setOrgModelMap(orgModelsList.stream() diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/PrequalificationDeclaredProjectManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/PrequalificationDeclaredProjectManage.java index 9653119..85c2156 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/PrequalificationDeclaredProjectManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/PrequalificationDeclaredProjectManage.java @@ -139,8 +139,8 @@ public class PrequalificationDeclaredProjectManage { ); params.setFormData(dto.getFormData()); - // 获取发起单位、发起单位主管单位信息 - Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId, model); + // 获取发起单位、发起单位主管单位、发起单位上级主管条线单位信息 + Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId); instanceId = processService.newStartProcess(model.getProcessDefId(),model.getFormId(), params,orgModelMap); log.info("提交预审项目成功 【{}】", instanceId); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByDeptJointManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByDeptJointManage.java index 911c6fe..5be0b00 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByDeptJointManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByDeptJointManage.java @@ -104,8 +104,8 @@ public class ReviewByDeptJointManage { ); params.setFormData(formData); - // 获取发起单位、发起单位主管单位信息 - Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId, model); + // 获取发起单位、发起单位主管单位、发起单位上级主管条线单位信息 + Map orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId); String instanceId = processService.newStartProcess(model.getProcessDefId(),model.getFormId(), params,orgModelMap); log.info("部门联审申报成功 【{}】", instanceId); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/helper/ProjectHelper.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/helper/ProjectHelper.java index b6fda91..2f43b1e 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/helper/ProjectHelper.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/helper/ProjectHelper.java @@ -50,7 +50,8 @@ public class ProjectHelper { .in(CollUtil.isNotEmpty(req.getStageList()),Project::getStage,req.getStageList()) .in(CollUtil.isNotEmpty(req.getStatusList()),Project::getStatus,req.getStatusList()) //实例code - .in(CollUtil.isNotEmpty(req.getInstCodes()),Project::getInstCode,req.getInstCodes()); + .in(CollUtil.isNotEmpty(req.getInstCodes()),Project::getInstCode,req.getInstCodes()) + .orderByDesc(Project::getCreateOn); return query; } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/InitProcessTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/InitProcessTask.java index 0218dda..c1cfbe1 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/InitProcessTask.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/InitProcessTask.java @@ -12,12 +12,10 @@ import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; import com.ningdatech.pmapi.common.helper.RegionCacheHelper; import com.ningdatech.pmapi.scheduler.contants.TaskContant; import com.ningdatech.pmapi.sys.model.dto.RegionDTO; -import com.ningdatech.pmapi.sys.model.entity.Region; import com.ningdatech.pmapi.sys.service.IRegionService; -import com.wflow.bean.dto.WflowModelHistorysDto; +import com.wflow.bean.dto.WflowModelHistorysInsertDto; import com.wflow.bean.entity.WflowForms; import com.wflow.bean.entity.WflowModels; -import com.wflow.workflow.bean.dto.OrgInfoDTO; import com.wflow.workflow.bean.process.ProcessNode; import com.wflow.workflow.service.ProcessModelService; import com.wflow.workflow.service.WflowFormsService; @@ -111,9 +109,9 @@ public class InitProcessTask { Integer[] processTypeList = TaskContant.Wflow.DEFAULT_PROCESS_TYPE_LIST; for(Integer processType : processTypeList){ String formName = ProjectProcessStageEnum.getDesc(processType); - WflowModelHistorysDto models = new WflowModelHistorysDto(); + WflowModelHistorysInsertDto models = new WflowModelHistorysInsertDto(); // models.setFormId("wf" + IdUtil.objectId()); - models.setVersion(1); +// models.setVersion(1); models.setGroupId(1); models.setProcessDefId("pd" + IdUtil.objectId()); models.setFormName(formName); @@ -125,7 +123,7 @@ public class InitProcessTask { models.setSettings("{\"sign\":false,\"admin\":[],\"notify\":{},\"commiter\":[]}"); models.setFormItems("[]"); - String formId = processModelService.saveProcess(models); + String formId = processModelService.insertProcess(models); if(StringUtils.isNotBlank(formId)){ //初始的流程在部署表也存一份,用来查询 if(StringUtils.isNotBlank(processModelService.deployProcess(formId,null))){ diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java index 488232c..d11230d 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java @@ -215,7 +215,7 @@ public class TodoCenterManage { Project declaredProject = projectService.getOne(Wrappers.lambdaQuery(Project.class) .eq(Project::getInstCode, processInstanceId) .eq(Project::getId, projectId)); - VUtils.isTrue(Objects.isNull(projectId)).throwMessage("获取项目ID失败!"); + VUtils.isTrue(Objects.isNull(declaredProject)).throwMessage("获取项目失败!"); // 获取当前项目名称 String projectName = declaredProject.getProjectName(); // 获取当前项目状态