@@ -262,6 +262,11 @@ | |||||
<groupId>com.itextpdf</groupId> | <groupId>com.itextpdf</groupId> | ||||
<artifactId>html2pdf</artifactId> | <artifactId>html2pdf</artifactId> | ||||
</dependency> | </dependency> | ||||
<!--导入导出--> | |||||
<dependency> | |||||
<groupId>cn.afterturn</groupId> | |||||
<artifactId>easypoi-base</artifactId> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
@@ -32,6 +32,7 @@ public interface CommonConst { | |||||
String ARCHIVED = "归档"; | String ARCHIVED = "归档"; | ||||
String FILE_NAME = "name"; | String FILE_NAME = "name"; | ||||
String BASIS_FILE_NAME = "fileName"; | |||||
String NULL = "null"; | String NULL = "null"; | ||||
@@ -45,6 +46,12 @@ public interface CommonConst { | |||||
String NEW_CONSTRUCTION = "新建"; | String NEW_CONSTRUCTION = "新建"; | ||||
String CONTINUED_CONSTRUCTION = "续建"; | String CONTINUED_CONSTRUCTION = "续建"; | ||||
String MONTH = "月"; | String MONTH = "月"; | ||||
String ZHI = "至"; | |||||
String YEAR = "年"; | |||||
Integer VERSION_ONE = 1; | |||||
Integer VERSION_SIZE = 2; | |||||
Integer VERSION_JUDGE = -1; | |||||
@@ -44,7 +44,7 @@ public class ProjectDeclareAction { | |||||
} | } | ||||
@OnTransition(source = "UNDER_INTERNAL_AUDIT_NOT_PASS", target = "UNDER_INTERNAL_AUDIT") | @OnTransition(source = "UNDER_INTERNAL_AUDIT_NOT_PASS", target = "UNDER_INTERNAL_AUDIT") | ||||
public void UNDER_INTERNAL_RESUBMIT(Message<ProjectStatusChangeEvent> message) { | |||||
public void UNDER_INTERNAL_REJECT_RESUBMIT(Message<ProjectStatusChangeEvent> message) { | |||||
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | ||||
project.setStatus(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode()); | project.setStatus(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode()); | ||||
} | } | ||||
@@ -99,6 +99,12 @@ public class ProjectDeclareAction { | |||||
project.setStatus(ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode()); | project.setStatus(ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode()); | ||||
} | } | ||||
@OnTransition(source = "PREQUALIFICATION_FAILED", target = "PENDING_PREQUALIFICATION_CHOICE") | |||||
public void PRELIMINARY_REVIEW_REJECT_RESUBMIT(Message<ProjectStatusChangeEvent> message) { | |||||
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | |||||
project.setStatus(ProjectStatusEnum.PENDING_PREQUALIFICATION_CHOICE.getCode()); | |||||
} | |||||
@OnTransition(source = "PRE_APPLYING", target = "PREQUALIFICATION_WITHDRAW_CHOICE") | @OnTransition(source = "PRE_APPLYING", target = "PREQUALIFICATION_WITHDRAW_CHOICE") | ||||
public void PRE_APPLYING_WITHDRAW(Message<ProjectStatusChangeEvent> message) { | public void PRE_APPLYING_WITHDRAW(Message<ProjectStatusChangeEvent> message) { | ||||
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | ||||
@@ -174,6 +180,12 @@ public class ProjectDeclareAction { | |||||
project.setStatus(ProjectStatusEnum.SCHEME_REVIEW_FAILED.getCode()); | project.setStatus(ProjectStatusEnum.SCHEME_REVIEW_FAILED.getCode()); | ||||
} | } | ||||
@OnTransition(source = "SCHEME_REVIEW_FAILED", target = "SCHEME_UNDER_REVIEW") | |||||
public void PLAN_REVIEW_REJECT_RESUBMIT(Message<ProjectStatusChangeEvent> message) { | |||||
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | |||||
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode()); | |||||
} | |||||
@OnTransition(source = "SCHEME_UNDER_REVIEW", target = "PLAN_TO_BE_DECLARED") | @OnTransition(source = "SCHEME_UNDER_REVIEW", target = "PLAN_TO_BE_DECLARED") | ||||
public void SCHEME_UNDER_REVIEW_WITHDRAW(Message<ProjectStatusChangeEvent> message) { | public void SCHEME_UNDER_REVIEW_WITHDRAW(Message<ProjectStatusChangeEvent> message) { | ||||
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | ||||
@@ -86,7 +86,7 @@ public class ProjectDeclareStateMachineBuilder { | |||||
.withExternal() | .withExternal() | ||||
.source(ProjectStatusEnum.UNDER_INTERNAL_AUDIT_NOT_PASS) | .source(ProjectStatusEnum.UNDER_INTERNAL_AUDIT_NOT_PASS) | ||||
.target(ProjectStatusEnum.UNDER_INTERNAL_AUDIT) | .target(ProjectStatusEnum.UNDER_INTERNAL_AUDIT) | ||||
.event(ProjectStatusChangeEvent.PROJECT_APPLICATION_SUBMIT).and() | |||||
.event(ProjectStatusChangeEvent.UNDER_INTERNAL_REJECT_RESUBMIT).and() | |||||
// 待预审预审申报,从待预审到待预审选择 | // 待预审预审申报,从待预审到待预审选择 | ||||
.withExternal() | .withExternal() | ||||
@@ -145,7 +145,7 @@ public class ProjectDeclareStateMachineBuilder { | |||||
.withExternal() | .withExternal() | ||||
.source(ProjectStatusEnum.PREQUALIFICATION_FAILED) | .source(ProjectStatusEnum.PREQUALIFICATION_FAILED) | ||||
.target(ProjectStatusEnum.PENDING_PREQUALIFICATION_CHOICE) | .target(ProjectStatusEnum.PENDING_PREQUALIFICATION_CHOICE) | ||||
.event(ProjectStatusChangeEvent.PRELIMINARY_REVIEW_DECLARE).and() | |||||
.event(ProjectStatusChangeEvent.PRELIMINARY_REVIEW_REJECT_RESUBMIT).and() | |||||
// 预审不通过重新提交,从待预审选择->省级部门联审中,预审中,完成其中一种状态 | // 预审不通过重新提交,从待预审选择->省级部门联审中,预审中,完成其中一种状态 | ||||
.withChoice() | .withChoice() | ||||
.source(ProjectStatusEnum.PENDING_PREQUALIFICATION_CHOICE) | .source(ProjectStatusEnum.PENDING_PREQUALIFICATION_CHOICE) | ||||
@@ -200,7 +200,7 @@ public class ProjectDeclareStateMachineBuilder { | |||||
.withExternal() | .withExternal() | ||||
.source(ProjectStatusEnum.SCHEME_REVIEW_FAILED) | .source(ProjectStatusEnum.SCHEME_REVIEW_FAILED) | ||||
.target(ProjectStatusEnum.SCHEME_UNDER_REVIEW) | .target(ProjectStatusEnum.SCHEME_UNDER_REVIEW) | ||||
.event(ProjectStatusChangeEvent.DECLARE_PLAN).and() | |||||
.event(ProjectStatusChangeEvent.PLAN_REVIEW_REJECT_RESUBMIT).and() | |||||
// 待立项批复批复,从待立项批复到待采购 | // 待立项批复批复,从待立项批复到待采购 | ||||
.withExternal() | .withExternal() | ||||
.source(ProjectStatusEnum.TO_BE_APPROVED) | .source(ProjectStatusEnum.TO_BE_APPROVED) | ||||
@@ -36,6 +36,11 @@ public enum ProjectStatusChangeEvent { | |||||
*/ | */ | ||||
UNDER_INTERNAL_PASS(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode(), null, null), | UNDER_INTERNAL_PASS(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode(), null, null), | ||||
/** | /** | ||||
* 单位内部审核不通过重新提交(项目状态进入:单位内部审核中) | |||||
*/ | |||||
UNDER_INTERNAL_REJECT_RESUBMIT(ProjectStatusEnum.UNDER_INTERNAL_AUDIT_NOT_PASS.getCode(),null,null), | |||||
/** | |||||
* 预审申报(项目状态进入:待预审选择,有判断条件:市级项目且申报金额大于1000万项目状态变为:省级部门联审中;否则项目状态变为:预审中) | * 预审申报(项目状态进入:待预审选择,有判断条件:市级项目且申报金额大于1000万项目状态变为:省级部门联审中;否则项目状态变为:预审中) | ||||
*/ | */ | ||||
PRELIMINARY_REVIEW_DECLARE(ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode(), null, null), | PRELIMINARY_REVIEW_DECLARE(ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode(), null, null), | ||||
@@ -57,6 +62,10 @@ public enum ProjectStatusChangeEvent { | |||||
*/ | */ | ||||
PRELIMINARY_REVIEW_REJECT(null, ProjectStatusEnum.PRE_APPLYING.getCode(), null), | PRELIMINARY_REVIEW_REJECT(null, ProjectStatusEnum.PRE_APPLYING.getCode(), null), | ||||
/** | /** | ||||
* 预审不通过重新提交(项目状态变为:待预审选择) | |||||
*/ | |||||
PRELIMINARY_REVIEW_REJECT_RESUBMIT(ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode(),null,null), | |||||
/** | |||||
* 预审通过(项目状态变为:部门联审中) | * 预审通过(项目状态变为:部门联审中) | ||||
*/ | */ | ||||
PRELIMINARY_REVIEW_PASS(ProjectStatusEnum.PRE_APPLYING.getCode(), null, null), | PRELIMINARY_REVIEW_PASS(ProjectStatusEnum.PRE_APPLYING.getCode(), null, null), | ||||
@@ -85,6 +94,10 @@ public enum ProjectStatusChangeEvent { | |||||
*/ | */ | ||||
PLAN_REVIEW_REJECT(null, ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode(), null), | PLAN_REVIEW_REJECT(null, ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode(), null), | ||||
/** | /** | ||||
* 方案评审不通过重新提交(项目状态变为:方案评审中) | |||||
*/ | |||||
PLAN_REVIEW_REJECT_RESUBMIT(ProjectStatusEnum.SCHEME_REVIEW_FAILED.getCode(),null,null), | |||||
/** | |||||
* 方案评审通过(项目状态变为:待立项批复) | * 方案评审通过(项目状态变为:待立项批复) | ||||
*/ | */ | ||||
PLAN_REVIEW_PASS(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode(), null, null), | PLAN_REVIEW_PASS(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode(), null, null), | ||||
@@ -105,4 +105,8 @@ public class BizUtils { | |||||
}))); | }))); | ||||
} | } | ||||
public static String inSqlJoin(List<String> strings) { | |||||
return strings.stream().map(w -> "'" + w + "'").collect(Collectors.joining(StrPool.COMMA, StrPool.LEFT_BRACKET, StrPool.RIGHT_BRACKET)); | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.ningdatech.basic.util.SpringUtils; | |||||
import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import java.io.Serializable; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Optional; | import java.util.Optional; | ||||
@@ -16,7 +17,7 @@ import java.util.Optional; | |||||
* @since 2022/1/9 23:28 | * @since 2022/1/9 23:28 | ||||
*/ | */ | ||||
@RequiredArgsConstructor | @RequiredArgsConstructor | ||||
public class DataScopeContext { | |||||
public class DataScopeContext implements Serializable { | |||||
private static final String WARN_MSG = "请先创建数据权限[%s]的实现类,使其实现 DataScopeProvider"; | private static final String WARN_MSG = "请先创建数据权限[%s]的实现类,使其实现 DataScopeProvider"; | ||||
@@ -5,6 +5,7 @@ import com.ningdatech.log.annotation.WebLog; | |||||
import com.ningdatech.pmapi.expert.manage.ExpertReviewManage; | import com.ningdatech.pmapi.expert.manage.ExpertReviewManage; | ||||
import com.ningdatech.pmapi.expert.model.req.ExpertReviewDetailReq; | import com.ningdatech.pmapi.expert.model.req.ExpertReviewDetailReq; | ||||
import com.ningdatech.pmapi.expert.model.vo.ExpertReviewDetailVO; | import com.ningdatech.pmapi.expert.model.vo.ExpertReviewDetailVO; | ||||
import com.ningdatech.pmapi.expert.model.vo.ProjectReviewDetailVO; | |||||
import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
import io.swagger.annotations.ApiImplicitParam; | import io.swagger.annotations.ApiImplicitParam; | ||||
import io.swagger.annotations.ApiImplicitParams; | import io.swagger.annotations.ApiImplicitParams; | ||||
@@ -38,14 +39,16 @@ public class ExpertReviewController { | |||||
expertReviewManage.expertReview(req); | expertReviewManage.expertReview(req); | ||||
} | } | ||||
@GetMapping("/detail/{projectId}/{userId}") | |||||
@GetMapping("/detail/{meetingId}/{projectId}/{userId}") | |||||
@ApiOperation("获取专家评审详情") | @ApiOperation("获取专家评审详情") | ||||
@ApiImplicitParams({ | @ApiImplicitParams({ | ||||
@ApiImplicitParam(name = "userId", value = "专家ID"), | @ApiImplicitParam(name = "userId", value = "专家ID"), | ||||
@ApiImplicitParam(name = "projectId", value = "项目ID") | @ApiImplicitParam(name = "projectId", value = "项目ID") | ||||
}) | }) | ||||
public ExpertReviewDetailVO getExpertReviewDetail(@PathVariable Long userId, @PathVariable Long projectId) { | |||||
return expertReviewManage.getExpertReviewDetail(userId, projectId); | |||||
public ExpertReviewDetailVO getExpertReviewDetail(@PathVariable Long userId, | |||||
@PathVariable Long projectId, | |||||
@PathVariable Long meetingId) { | |||||
return expertReviewManage.getExpertReviewDetail(userId, projectId, meetingId); | |||||
} | } | ||||
@GetMapping("/listForGroupLeader/{projectId}/{meetingId}") | @GetMapping("/listForGroupLeader/{projectId}/{meetingId}") | ||||
@@ -70,4 +73,13 @@ public class ExpertReviewController { | |||||
return expertReviewManage.listReviews(projectId, meetingId, false); | return expertReviewManage.listReviews(projectId, meetingId, false); | ||||
} | } | ||||
@GetMapping("/detail/{projectId}") | |||||
@ApiImplicitParams({ | |||||
@ApiImplicitParam(name = "projectId", value = "项目ID"), | |||||
}) | |||||
@ApiOperation("查看项目的所有评审意见") | |||||
public ProjectReviewDetailVO projectExpertReviewDetail(@PathVariable Long projectId) { | |||||
return expertReviewManage.projectExpertReviewDetail(projectId); | |||||
} | |||||
} | } |
@@ -10,19 +10,25 @@ import com.ningdatech.file.entity.vo.result.AttachFileVo; | |||||
import com.ningdatech.file.service.FileService; | import com.ningdatech.file.service.FileService; | ||||
import com.ningdatech.pmapi.expert.model.dto.ReviewTemplateOptionDTO; | import com.ningdatech.pmapi.expert.model.dto.ReviewTemplateOptionDTO; | ||||
import com.ningdatech.pmapi.expert.model.entity.ExpertReview; | import com.ningdatech.pmapi.expert.model.entity.ExpertReview; | ||||
import com.ningdatech.pmapi.expert.model.entity.ReviewTemplateSettings; | |||||
import com.ningdatech.pmapi.expert.model.req.ExpertReviewDetailReq; | import com.ningdatech.pmapi.expert.model.req.ExpertReviewDetailReq; | ||||
import com.ningdatech.pmapi.expert.model.vo.ExpertReviewDetailVO; | import com.ningdatech.pmapi.expert.model.vo.ExpertReviewDetailVO; | ||||
import com.ningdatech.pmapi.expert.model.vo.ProjectReviewDetailVO; | |||||
import com.ningdatech.pmapi.expert.model.vo.ReviewTemplateVO; | |||||
import com.ningdatech.pmapi.expert.service.IExpertReviewService; | import com.ningdatech.pmapi.expert.service.IExpertReviewService; | ||||
import com.ningdatech.pmapi.expert.service.IReviewTemplateSettingsService; | |||||
import com.ningdatech.pmapi.meeting.entity.domain.Meeting; | |||||
import com.ningdatech.pmapi.meeting.service.IMeetingExpertService; | import com.ningdatech.pmapi.meeting.service.IMeetingExpertService; | ||||
import com.ningdatech.pmapi.meeting.service.IMeetingInnerProjectService; | |||||
import com.ningdatech.pmapi.meeting.service.IMeetingService; | |||||
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; | ||||
import java.util.Collections; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.*; | |||||
import java.util.stream.Collectors; | |||||
import static com.ningdatech.pmapi.expert.model.vo.ProjectReviewDetailVO.ReviewDetailByTypeVO; | |||||
import static com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum.AGREED; | import static com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum.AGREED; | ||||
/** | /** | ||||
@@ -41,6 +47,9 @@ public class ExpertReviewManage { | |||||
private final DistributedLock distributedLock; | private final DistributedLock distributedLock; | ||||
private final IMeetingExpertService meetingExpertService; | private final IMeetingExpertService meetingExpertService; | ||||
private final FileService fileService; | private final FileService fileService; | ||||
private final IMeetingInnerProjectService meetingInnerProjectService; | |||||
private final IMeetingService meetingService; | |||||
private final IReviewTemplateSettingsService templateSettingsService; | |||||
private static final String EXPERT_REVIEW_KEY = "expert_review:"; | private static final String EXPERT_REVIEW_KEY = "expert_review:"; | ||||
@@ -65,12 +74,13 @@ public class ExpertReviewManage { | |||||
public void expertReview(ExpertReviewDetailReq req) { | public void expertReview(ExpertReviewDetailReq req) { | ||||
Long userId = LoginUserUtil.getUserId(); | Long userId = LoginUserUtil.getUserId(); | ||||
Long projectId = req.getProjectId(); | Long projectId = req.getProjectId(); | ||||
Long meetingId = req.getMeetingId(); | |||||
String expertReviewKey = buildExpertReviewKey(projectId, userId); | String expertReviewKey = buildExpertReviewKey(projectId, userId); | ||||
if (!distributedLock.lock(expertReviewKey)) { | if (!distributedLock.lock(expertReviewKey)) { | ||||
throw BizException.wrap("保存评审意见失败,请重试"); | throw BizException.wrap("保存评审意见失败,请重试"); | ||||
} | } | ||||
try { | try { | ||||
List<ExpertReview> reviews = expertReviewService.listByProjectIdAndExpertId(projectId, userId); | |||||
List<ExpertReview> reviews = expertReviewService.listByProjectIdAndExpertId(projectId, userId, meetingId); | |||||
if (req.getIsFinal()) { | if (req.getIsFinal()) { | ||||
if (reviews.isEmpty()) { | if (reviews.isEmpty()) { | ||||
throw BizException.wrap("请先填写个人评审意见"); | throw BizException.wrap("请先填写个人评审意见"); | ||||
@@ -109,8 +119,8 @@ public class ExpertReviewManage { | |||||
} | } | ||||
} | } | ||||
public ExpertReviewDetailVO getExpertReviewDetail(Long projectId, Long userId) { | |||||
List<ExpertReview> reviews = expertReviewService.listByProjectIdAndExpertId(projectId, userId); | |||||
public ExpertReviewDetailVO getExpertReviewDetail(Long projectId, Long userId, Long meetingId) { | |||||
List<ExpertReview> reviews = expertReviewService.listByProjectIdAndExpertId(projectId, userId, meetingId); | |||||
reviews.removeIf(ExpertReview::getIsFinal); | reviews.removeIf(ExpertReview::getIsFinal); | ||||
if (reviews.isEmpty()) { | if (reviews.isEmpty()) { | ||||
throw BizException.wrap("评审记录不存在"); | throw BizException.wrap("评审记录不存在"); | ||||
@@ -141,4 +151,51 @@ public class ExpertReviewManage { | |||||
}); | }); | ||||
} | } | ||||
public ProjectReviewDetailVO projectExpertReviewDetail(Long projectId) { | |||||
ProjectReviewDetailVO detail = new ProjectReviewDetailVO(); | |||||
List<Long> meetingIds = meetingInnerProjectService.listMeetingIdByProjectId(projectId); | |||||
if (meetingIds.isEmpty()) { | |||||
return detail; | |||||
} | |||||
List<Meeting> meetings = meetingService.listByIds(meetingIds); | |||||
Collection<Long> tmpMeetingIds = meetings.stream() | |||||
.collect(Collectors.groupingBy(Meeting::getType, | |||||
Collectors.collectingAndThen(Collectors.toList(), w -> { | |||||
w.sort(Comparator.comparing(Meeting::getCreateOn)); | |||||
return w.get(w.size() - 1).getId(); | |||||
}))).values(); | |||||
LambdaQueryWrapper<ExpertReview> erQuery = Wrappers.lambdaQuery(ExpertReview.class) | |||||
.in(ExpertReview::getMeetingId, tmpMeetingIds) | |||||
.eq(ExpertReview::getProjectId, projectId) | |||||
.orderByDesc(ExpertReview::getCreateOn); | |||||
List<ExpertReview> expertReviews = expertReviewService.list(erQuery); | |||||
if (expertReviews.isEmpty()) { | |||||
return detail; | |||||
} | |||||
List<Long> templateIds = CollUtils.fieldList(expertReviews, ExpertReview::getTemplateId); | |||||
List<ReviewTemplateSettings> templates = templateSettingsService.listByIds(templateIds); | |||||
Map<Long, ReviewTemplateVO> templateMap = CollUtils.listToMap(templates, | |||||
ReviewTemplateSettings::getId, | |||||
ReviewTemplateSettingsManage::buildTemplateDetail); | |||||
detail.setTemplates(templateMap.values()); | |||||
Map<Integer, ReviewDetailByTypeVO> map = new HashMap<>(8); | |||||
expertReviews.forEach(review -> { | |||||
ReviewTemplateVO template = templateMap.get(review.getTemplateId()); | |||||
ReviewDetailByTypeVO reviewDetailByType = map.computeIfAbsent(template.getTemplateType(), k -> { | |||||
ReviewDetailByTypeVO tmpReviewDetail = new ReviewDetailByTypeVO(); | |||||
tmpReviewDetail.setReviewType(k); | |||||
tmpReviewDetail.setTeamMemberReviews(new ArrayList<>()); | |||||
return tmpReviewDetail; | |||||
}); | |||||
ExpertReviewDetailVO tmpReview = buildExpertReviewDetail(review); | |||||
if (review.getIsFinal()) { | |||||
reviewDetailByType.setFinalReview(tmpReview); | |||||
} else { | |||||
reviewDetailByType.getTeamMemberReviews().add(tmpReview); | |||||
} | |||||
}); | |||||
detail.setReviews(map.values()); | |||||
return detail; | |||||
} | |||||
} | } |
@@ -67,10 +67,10 @@ public class ReviewTemplateSettingsManage { | |||||
public List<ReviewTemplateVO> listReviewTemplateSettings(List<Long> templateIds) { | public List<ReviewTemplateVO> listReviewTemplateSettings(List<Long> templateIds) { | ||||
List<ReviewTemplateSettings> settings = reviewTemplateSettingsService.listByIds(templateIds); | List<ReviewTemplateSettings> settings = reviewTemplateSettingsService.listByIds(templateIds); | ||||
return CollUtils.convert(settings, this::buildTemplateDetail); | |||||
return CollUtils.convert(settings, ReviewTemplateSettingsManage::buildTemplateDetail); | |||||
} | } | ||||
private ReviewTemplateVO buildTemplateDetail(ReviewTemplateSettings settings) { | |||||
protected static ReviewTemplateVO buildTemplateDetail(ReviewTemplateSettings settings) { | |||||
if (settings == null) { | if (settings == null) { | ||||
throw BizException.wrap("模版不存在"); | throw BizException.wrap("模版不存在"); | ||||
} | } | ||||
@@ -0,0 +1,40 @@ | |||||
package com.ningdatech.pmapi.expert.model.vo; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import java.util.Collection; | |||||
import java.util.List; | |||||
/** | |||||
* <p> | |||||
* ProjectExpertReviewDetailVO | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023/4/19 | |||||
**/ | |||||
@Data | |||||
public class ProjectReviewDetailVO { | |||||
@ApiModelProperty("评审模版详情") | |||||
private Collection<ReviewTemplateVO> templates; | |||||
private Collection<ReviewDetailByTypeVO> reviews; | |||||
@Data | |||||
public static class ReviewDetailByTypeVO { | |||||
@ApiModelProperty("评审类型") | |||||
private Integer reviewType; | |||||
@ApiModelProperty("最终评审意见") | |||||
private ExpertReviewDetailVO finalReview; | |||||
@ApiModelProperty("组员评审意见") | |||||
private List<ExpertReviewDetailVO> teamMemberReviews; | |||||
} | |||||
} |
@@ -21,10 +21,11 @@ public interface IExpertReviewService extends IService<ExpertReview> { | |||||
* | * | ||||
* @param projectId 项目ID | * @param projectId 项目ID | ||||
* @param expertId 专家ID | * @param expertId 专家ID | ||||
* @param meetingId 会议ID | |||||
* @return 评审记录 | * @return 评审记录 | ||||
* @author WendyYang | * @author WendyYang | ||||
**/ | **/ | ||||
List<ExpertReview> listByProjectIdAndExpertId(Long projectId, Long expertId); | |||||
List<ExpertReview> listByProjectIdAndExpertId(Long projectId, Long expertId, Long meetingId); | |||||
/** | /** | ||||
* 获取最终评审结果 | * 获取最终评审结果 | ||||
@@ -1,8 +1,13 @@ | |||||
package com.ningdatech.pmapi.expert.service; | package com.ningdatech.pmapi.expert.service; | ||||
import cn.hutool.core.collection.CollUtil; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.baomidou.mybatisplus.extension.service.IService; | import com.baomidou.mybatisplus.extension.service.IService; | ||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; | import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; | ||||
import java.util.Collection; | |||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
@@ -33,7 +38,6 @@ public interface IExpertUserFullInfoService extends IService<ExpertUserFullInfo> | |||||
List<ExpertUserFullInfo> listByUserId(List<Long> userId); | List<ExpertUserFullInfo> listByUserId(List<Long> userId); | ||||
/** | /** | ||||
* 批量查询专家用户信息 | * 批量查询专家用户信息 | ||||
* | * | ||||
@@ -42,4 +46,12 @@ public interface IExpertUserFullInfoService extends IService<ExpertUserFullInfo> | |||||
*/ | */ | ||||
List<ExpertUserFullInfo> listByUserIds(List<Long> userIds); | List<ExpertUserFullInfo> listByUserIds(List<Long> userIds); | ||||
default List<String> listCompanyUniqCodeByUserIds(Collection<Long> userIds) { | |||||
LambdaQueryWrapper<ExpertUserFullInfo> query = Wrappers | |||||
.lambdaQuery(ExpertUserFullInfo.class) | |||||
.select(ExpertUserFullInfo::getCompanyUniqCode) | |||||
.in(ExpertUserFullInfo::getUserId, userIds); | |||||
return CollUtils.fieldList(list(query), ExpertUserFullInfo::getCompanyUniqCode); | |||||
} | |||||
} | } |
@@ -25,10 +25,11 @@ import java.util.Map; | |||||
public class ExpertReviewServiceImpl extends ServiceImpl<ExpertReviewMapper, ExpertReview> implements IExpertReviewService { | public class ExpertReviewServiceImpl extends ServiceImpl<ExpertReviewMapper, ExpertReview> implements IExpertReviewService { | ||||
@Override | @Override | ||||
public List<ExpertReview> listByProjectIdAndExpertId(Long projectId, Long expertId) { | |||||
public List<ExpertReview> listByProjectIdAndExpertId(Long projectId, Long expertId, Long meetingId) { | |||||
LambdaQueryWrapper<ExpertReview> query = Wrappers.lambdaQuery(ExpertReview.class); | LambdaQueryWrapper<ExpertReview> query = Wrappers.lambdaQuery(ExpertReview.class); | ||||
query.eq(ExpertReview::getProjectId, projectId); | query.eq(ExpertReview::getProjectId, projectId); | ||||
query.eq(ExpertReview::getCreateBy, expertId); | query.eq(ExpertReview::getCreateBy, expertId); | ||||
query.eq(ExpertReview::getMeetingId, meetingId); | |||||
query.orderByAsc(ExpertReview::getCreateOn); | query.orderByAsc(ExpertReview::getCreateOn); | ||||
return list(query); | return list(query); | ||||
} | } | ||||
@@ -1,8 +1,6 @@ | |||||
package com.ningdatech.pmapi.leave.entity.domain; | 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 com.baomidou.mybatisplus.annotation.*; | |||||
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; | ||||
@@ -48,15 +46,19 @@ public class ExpertLeave implements Serializable { | |||||
private String creator; | private String creator; | ||||
@ApiModelProperty("创建人") | @ApiModelProperty("创建人") | ||||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||||
private Long createBy; | private Long createBy; | ||||
@ApiModelProperty("创建时间") | @ApiModelProperty("创建时间") | ||||
@TableField(fill = FieldFill.INSERT) | |||||
private LocalDateTime createOn; | private LocalDateTime createOn; | ||||
@ApiModelProperty("修改人") | @ApiModelProperty("修改人") | ||||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||||
private Long updateBy; | private Long updateBy; | ||||
@ApiModelProperty("修改时间") | @ApiModelProperty("修改时间") | ||||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||||
private LocalDateTime updateOn; | private LocalDateTime updateOn; | ||||
@ApiModelProperty("请假开始时间") | @ApiModelProperty("请假开始时间") | ||||
@@ -75,9 +77,4 @@ public class ExpertLeave implements Serializable { | |||||
private Integer status; | private Integer status; | ||||
public void setUpdateAndCreate(Long createBy, LocalDateTime createOn) { | |||||
this.updateBy = this.createBy = createBy; | |||||
this.updateOn = this.createOn = createOn; | |||||
} | |||||
} | } |
@@ -150,7 +150,7 @@ public class LeaveManage { | |||||
leave.setType(po.getType()); | leave.setType(po.getType()); | ||||
leave.setRemark(po.getPostscript()); | leave.setRemark(po.getPostscript()); | ||||
leave.setLeaveUserId(leaveUserId); | leave.setLeaveUserId(leaveUserId); | ||||
leave.setUpdateAndCreate(applyUserId, now); | |||||
leave.setCreator(LoginUserUtil.getUsername()); | |||||
List<KeyValDTO<LocalDateTime, LocalDateTime>> leaveDetailTimes = new ArrayList<>(); | List<KeyValDTO<LocalDateTime, LocalDateTime>> leaveDetailTimes = new ArrayList<>(); | ||||
if (type.equals(LeaveTypeEnum.FIXED_TERM) || type.equals(LeaveTypeEnum.LONG_TERM)) { | if (type.equals(LeaveTypeEnum.FIXED_TERM) || type.equals(LeaveTypeEnum.LONG_TERM)) { | ||||
boolean fixedTerm = CollUtil.isNotEmpty(po.getFixedType()); | boolean fixedTerm = CollUtil.isNotEmpty(po.getFixedType()); | ||||
@@ -215,6 +215,12 @@ public class LeaveManage { | |||||
if (ExpertInviteTypeEnum.RANDOM.eq(meeting.getInviteType())) { | if (ExpertInviteTypeEnum.RANDOM.eq(meeting.getInviteType())) { | ||||
inviteTask.notifyInviteTask(meeting.getId(), Boolean.FALSE); | inviteTask.notifyInviteTask(meeting.getId(), Boolean.FALSE); | ||||
} | } | ||||
if (meeting.getConfirmedRoster()) { | |||||
LambdaUpdateWrapper<Meeting> mUpdate = Wrappers.lambdaUpdate(Meeting.class) | |||||
.set(Meeting::getConfirmedRoster, Boolean.FALSE) | |||||
.eq(Meeting::getId, meeting.getId()); | |||||
meetingService.update(mUpdate); | |||||
} | |||||
// 临时请假无需审核 | // 临时请假无需审核 | ||||
leave.setAuditId(0L); | leave.setAuditId(0L); | ||||
leave.setStatus(LeaveStatusEnum.PASSED.getCode()); | leave.setStatus(LeaveStatusEnum.PASSED.getCode()); | ||||
@@ -0,0 +1,24 @@ | |||||
package com.ningdatech.pmapi.meeting.constant; | |||||
/** | |||||
* <p> | |||||
* MeetingMsgConst | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023/4/20 | |||||
**/ | |||||
public interface MeetingMsgTemplateConst { | |||||
/** | |||||
* 已结束:自动抽取结束,结束时给会议发起人发送浙政钉工作通知、短信:“注意,xxx会议自动抽取已结束,请及时确认是否召开会议”。 | |||||
*/ | |||||
String INVITE_END = "注意,%s会议自动抽取已结束,请及时确认是否召开会议"; | |||||
/** | |||||
* 尊敬的【姓名】专家您好,您于【确认时间】接受了信息化项目评审会议邀请,会议时间:【会议时间】,会议地点:【会议地点】。请准时参加评审会议。如有疑问请联系【联系人】(【联系方式】)。 | |||||
*/ | |||||
String CONFIRMED_ROSTER = "尊敬的%s专家您好,您于%s接受了信息化项目评审会议邀请,会议时间:%s,会议地点:%s。请准时参加评审会议。如有疑问请联系%s(%s)。"; | |||||
} |
@@ -153,6 +153,13 @@ public class MeetingController { | |||||
meetingManage.confirmAttendByManager(req); | meetingManage.confirmAttendByManager(req); | ||||
} | } | ||||
@ApiOperation("专家移除") | |||||
@PostMapping("/expertRemove") | |||||
@WebLog(value = "专家移除") | |||||
public void expertRemove(@Valid @RequestBody ExpertRemoveReq req) { | |||||
meetingManage.expertRemove(req); | |||||
} | |||||
@ApiOperation("释放专家") | @ApiOperation("释放专家") | ||||
@PostMapping("/expert/release") | @PostMapping("/expert/release") | ||||
@WebLog(value = "释放专家") | @WebLog(value = "释放专家") | ||||
@@ -167,11 +174,11 @@ public class MeetingController { | |||||
meetingManage.setUpHeadman(req); | meetingManage.setUpHeadman(req); | ||||
} | } | ||||
@ApiOperation("重发短信") | |||||
@ApiOperation("重发短信 | 确认名单") | |||||
@PostMapping("/confirmedRoster") | @PostMapping("/confirmedRoster") | ||||
@WebLog(value = "重发短信") | @WebLog(value = "重发短信") | ||||
public void resendSms(@RequestBody MeetingCancelReq req) { | |||||
meetingManage.confirmedRoster(req.getMeetingId()); | |||||
public void resendSms(@RequestBody ConfirmedRosterReq req) { | |||||
meetingManage.confirmedRoster(req); | |||||
} | } | ||||
@GetMapping("/listReviewProject") | @GetMapping("/listReviewProject") | ||||
@@ -56,6 +56,9 @@ public class MeetingExpert implements Serializable { | |||||
@ApiModelProperty("邀请类型") | @ApiModelProperty("邀请类型") | ||||
private Integer inviteType; | private Integer inviteType; | ||||
@ApiModelProperty("是否已确认名单") | |||||
private Boolean confirmedRoster; | |||||
private String submitKey; | private String submitKey; | ||||
@TableField(fill = FieldFill.INSERT) | @TableField(fill = FieldFill.INSERT) | ||||
@@ -0,0 +1,28 @@ | |||||
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 10:43 2022/8/26 | |||||
*/ | |||||
@Data | |||||
@ApiModel("会议确认名单实体") | |||||
public class ConfirmedRosterReq { | |||||
@NotNull(message = "会议ID不能为空") | |||||
@ApiModelProperty("会议ID") | |||||
private Long meetingId; | |||||
@ApiModelProperty | |||||
private Boolean reconfirmed; | |||||
} |
@@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | import io.swagger.annotations.ApiModelProperty; | ||||
import lombok.Data; | import lombok.Data; | ||||
import javax.validation.constraints.NotNull; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
* ExpertRemovePo | * ExpertRemovePo | ||||
@@ -13,15 +15,14 @@ import lombok.Data; | |||||
* @since 08:59 2022/8/10 | * @since 08:59 2022/8/10 | ||||
*/ | */ | ||||
@Data | @Data | ||||
@ApiModel("专家(移除/替换)实体") | |||||
@ApiModel("专家移除实体") | |||||
public class ExpertRemoveReq { | public class ExpertRemoveReq { | ||||
@NotNull(message = "会议ID不能为空") | |||||
@ApiModelProperty("会议ID") | @ApiModelProperty("会议ID") | ||||
private Long meetingId; | private Long meetingId; | ||||
@ApiModelProperty("专家ID") | |||||
private Long expertId; | |||||
@NotNull(message = "专家会议ID不能为空") | |||||
@ApiModelProperty("专家会议ID") | @ApiModelProperty("专家会议ID") | ||||
private Long expertMeetingId; | private Long expertMeetingId; | ||||
@@ -0,0 +1,28 @@ | |||||
package com.ningdatech.pmapi.meeting.entity.req; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
/** | |||||
* <p> | |||||
* ExpertRemovePo | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 08:59 2022/8/10 | |||||
*/ | |||||
@Data | |||||
@ApiModel("专家替换实体") | |||||
public class ExpertReplaceReq { | |||||
@ApiModelProperty("会议ID") | |||||
private Long meetingId; | |||||
@ApiModelProperty("专家ID") | |||||
private Long expertId; | |||||
@ApiModelProperty("专家会议ID") | |||||
private Long expertMeetingId; | |||||
} |
@@ -36,6 +36,8 @@ public class MeetingDetailBasicVO { | |||||
@ApiModelProperty("会议类型名称") | @ApiModelProperty("会议类型名称") | ||||
private String typeName; | private String typeName; | ||||
private String regionCode; | |||||
@ApiModelProperty("会议类型代码") | @ApiModelProperty("会议类型代码") | ||||
private String meetingType; | private String meetingType; | ||||
@@ -0,0 +1,151 @@ | |||||
package com.ningdatech.pmapi.meeting.helper; | |||||
import cn.hutool.core.date.DatePattern; | |||||
import cn.hutool.core.util.StrUtil; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.ningdatech.pmapi.meeting.constant.MeetingMsgTemplateConst; | |||||
import com.ningdatech.pmapi.meeting.entity.domain.Meeting; | |||||
import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpert; | |||||
import com.ningdatech.pmapi.organization.model.entity.DingEmployeeInfo; | |||||
import com.ningdatech.pmapi.organization.model.entity.DingOrganization; | |||||
import com.ningdatech.pmapi.organization.service.IDingEmployeeInfoService; | |||||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | |||||
import com.ningdatech.pmapi.sys.model.entity.Notify; | |||||
import com.ningdatech.pmapi.sys.service.INotifyService; | |||||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | |||||
import com.ningdatech.pmapi.user.entity.UserInfo; | |||||
import com.ningdatech.pmapi.user.service.IUserInfoService; | |||||
import com.ningdatech.yxt.model.cmd.SendSmsCmd.SendSmsContext; | |||||
import lombok.AllArgsConstructor; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
import java.time.LocalDateTime; | |||||
import java.util.ArrayList; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* <p> | |||||
* MeetingMsgHelper | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023/4/20 | |||||
**/ | |||||
@Component | |||||
@AllArgsConstructor | |||||
public class MeetingMsgHelper { | |||||
private final IUserInfoService userInfoService; | |||||
private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | |||||
private final INdWorkNoticeStagingService workNoticeStagingService; | |||||
private final IDingEmployeeInfoService dingEmployeeInfoService; | |||||
private final IDingOrganizationService dingOrganizationService; | |||||
private final INotifyService notifyService; | |||||
private static String officialTime(LocalDateTime time) { | |||||
return time.format(DatePattern.NORM_DATETIME_MINUTE_FORMATTER); | |||||
} | |||||
private Notify getNotify(Long userId, String msg, MsgTypeEnum type, Map<String, Object> extraPara) { | |||||
Notify notify = new Notify(); | |||||
notify.setUserId(userId); | |||||
notify.setContent(msg); | |||||
notify.setType(type.name()); | |||||
notify.setReaded(Boolean.FALSE); | |||||
notify.setCreateTime(LocalDateTime.now()); | |||||
String extraJson = JSON.toJSONString(extraPara); | |||||
notify.setExtraInfo(extraJson); | |||||
return notify; | |||||
} | |||||
private WorkNoticeInfo getSendWorkNoticeInfo(Long accountId) { | |||||
WorkNoticeInfo workNoticeInfo = new WorkNoticeInfo(); | |||||
workNoticeInfo.setAccountId(accountId); | |||||
// 根据浙政钉用户ID获取部门code | |||||
DingEmployeeInfo employeeInfo = dingEmployeeInfoService.getOne(Wrappers.lambdaQuery(DingEmployeeInfo.class) | |||||
.eq(DingEmployeeInfo::getAccountId, accountId) | |||||
.eq(DingEmployeeInfo::getMainJob, String.valueOf(Boolean.TRUE)) | |||||
.last("limit 1")); | |||||
String organizationCode = employeeInfo.getOrganizationCode(); | |||||
workNoticeInfo.setOrganizationCode(organizationCode); | |||||
// 根据部门code获取部门名称 | |||||
DingOrganization dingOrganization = dingOrganizationService.getOne(Wrappers.lambdaQuery(DingOrganization.class) | |||||
.eq(DingOrganization::getOrganizationCode, organizationCode)); | |||||
String organizationName = dingOrganization.getOrganizationName(); | |||||
workNoticeInfo.setOrganizationName(organizationName); | |||||
// 构建唯一的消息ID | |||||
String bizMsgId = "ZD_WORK_NOTICE_" + StrUtil.UNDERLINE + organizationCode + StrUtil.UNDERLINE | |||||
+ organizationName + accountId + StrUtil.UNDERLINE + System.currentTimeMillis(); | |||||
workNoticeInfo.setBizMsgId(bizMsgId); | |||||
String receiverUserId = String.valueOf(accountId); | |||||
workNoticeInfo.setReceiverUserId(receiverUserId); | |||||
return workNoticeInfo; | |||||
} | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void sendInviteStopMsg(Long userId, Long meetingId, String meetingName) { | |||||
UserInfo info = userInfoService.getById(userId); | |||||
String msgContent = String.format(MeetingMsgTemplateConst.INVITE_END, meetingName); | |||||
// 音信通消息 | |||||
SendSmsContext yxtContent = new SendSmsContext(); | |||||
yxtContent.setContent(msgContent); | |||||
yxtContent.setReceiveNumber(info.getMobile()); | |||||
yxtCallOrSmsHelper.sendSms(yxtContent); | |||||
// 发送工作通知 | |||||
if (info.getAccountId() != null) { | |||||
WorkNoticeInfo swn = getSendWorkNoticeInfo(info.getAccountId()); | |||||
swn.setMsg(msgContent); | |||||
workNoticeStagingService.addByWorkNotice(swn, MsgTypeEnum.REVIEW_MEETING); | |||||
Map<String, Object> map = new HashMap<>(); | |||||
map.put("meetingId", meetingId); | |||||
Notify notify = getNotify(userId, msgContent, MsgTypeEnum.REVIEW_MEETING, map); | |||||
notifyService.save(notify); | |||||
} | |||||
} | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void sendConfirmedRosterMsg(List<MeetingExpert> experts, Meeting meeting) { | |||||
List<Long> userIds = CollUtils.fieldList(experts, MeetingExpert::getExpertId); | |||||
List<UserInfo> userInfos = userInfoService.listByIds(userIds); | |||||
Map<Long, UserInfo> userMap = CollUtils.listToMap(userInfos, UserInfo::getId); | |||||
String sTime = officialTime(meeting.getStartTime()); | |||||
String eTime = officialTime(meeting.getEndTime()); | |||||
String meetingTime = sTime + "至" + eTime; | |||||
List<SendSmsContext> yxtContents = new ArrayList<>(); | |||||
List<Notify> notifies = new ArrayList<>(); | |||||
List<WorkNoticeInfo> workingNotices = new ArrayList<>(); | |||||
experts.forEach(w -> { | |||||
String msgContent = String.format(MeetingMsgTemplateConst.CONFIRMED_ROSTER, | |||||
w.getExpertName(), officialTime(w.getCreateOn()), meetingTime, meeting.getMeetingAddress(), | |||||
meeting.getConnecter(), meeting.getContact()); | |||||
// 音信通消息 | |||||
SendSmsContext yxtContent = new SendSmsContext(); | |||||
yxtContent.setContent(msgContent); | |||||
yxtContent.setReceiveNumber(w.getMobile()); | |||||
yxtContents.add(yxtContent); | |||||
UserInfo info = userMap.get(w.getExpertId()); | |||||
// 发送工作通知 | |||||
if (info.getAccountId() != null) { | |||||
WorkNoticeInfo swn = getSendWorkNoticeInfo(info.getAccountId()); | |||||
swn.setMsg(msgContent); | |||||
workingNotices.add(swn); | |||||
Map<String, Object> map = new HashMap<>(); | |||||
map.put("meetingId", meeting.getId()); | |||||
Notify notify = getNotify(info.getId(), msgContent, MsgTypeEnum.EXPERT_REVIEW, map); | |||||
notifies.add(notify); | |||||
} | |||||
}); | |||||
notifyService.saveBatch(notifies); | |||||
yxtCallOrSmsHelper.sendSms(yxtContents); | |||||
workNoticeStagingService.addByWorkNotice(workingNotices, MsgTypeEnum.EXPERT_REVIEW); | |||||
} | |||||
} |
@@ -70,6 +70,9 @@ public class ExpertInviteManage { | |||||
@Value("#{randomInviteProperties.recentMeetingCount}") | @Value("#{randomInviteProperties.recentMeetingCount}") | ||||
private Integer recentMeetingCount; | private Integer recentMeetingCount; | ||||
@Value("#{randomInviteProperties.recentDays}") | |||||
private Integer recentDays; | |||||
private static final Predicate<Collection<?>> COLL_EMPTY = (coll) -> coll != null && coll.isEmpty(); | private static final Predicate<Collection<?>> COLL_EMPTY = (coll) -> coll != null && coll.isEmpty(); | ||||
private LambdaQueryWrapper<ExpertUserFullInfo> buildBaseExpertQuery() { | private LambdaQueryWrapper<ExpertUserFullInfo> buildBaseExpertQuery() { | ||||
@@ -83,6 +86,36 @@ public class ExpertInviteManage { | |||||
.eq(ExpertUserFullInfo::getExpertAccountStatus, ExpertAccountStatusEnum.AVAILABLE.getKey()); | .eq(ExpertUserFullInfo::getExpertAccountStatus, ExpertAccountStatusEnum.AVAILABLE.getKey()); | ||||
} | } | ||||
private void buildAvoidCompanyAndBusinessStrip(LambdaQueryWrapper<ExpertUserFullInfo> query, List<String> units, List<String> strips) { | |||||
if (CollUtil.isNotEmpty(units)) { | |||||
String unitStr = BizUtils.inSqlJoin(units); | |||||
query.notExists("select 1 from expert_avoid_company eac where eac.user_id = nd_expert_user_full_info.user_id" + | |||||
" and company_uniq_code in " + unitStr); | |||||
} | |||||
if (CollUtil.isNotEmpty(strips)) { | |||||
String orgStr = BizUtils.inSqlJoin(strips); | |||||
query.notExists("select 1 from expert_gov_business_strip egbs where egbs.expert_user_id = nd_expert_user_full_info.user_id" + | |||||
" and business_strip_code in " + orgStr); | |||||
} | |||||
} | |||||
/** | |||||
* 获取一周内被抽中并同意参会的专家ID | |||||
* | |||||
* @param agreeCnt 一周内被抽中并同意参会次数 | |||||
* @param sTime 会议开始时间 | |||||
* @param days 天数 | |||||
* @return java.util.List<java.lang.Long> | |||||
* @author WendyYang | |||||
**/ | |||||
private List<Long> listAgreedUserIdByRecentMeetings(int agreeCnt, int days, LocalDateTime sTime) { | |||||
if (agreeCnt == 0 || days == 0) { | |||||
return Collections.emptyList(); | |||||
} | |||||
LocalDateTime beginLimit = sTime.minusDays(days); | |||||
return meetingExpertService.listAgreeExpertIdByRecentDaysAndAgreeCount(agreeCnt, beginLimit, sTime); | |||||
} | |||||
/** | /** | ||||
* 增加专家层级限制 | * 增加专家层级限制 | ||||
* | * | ||||
@@ -249,13 +282,13 @@ public class ExpertInviteManage { | |||||
* | * | ||||
* @param avoidRule 回避信息 | * @param avoidRule 回避信息 | ||||
* @param randomRule 抽取规则 | * @param randomRule 抽取规则 | ||||
* @param appointExpertIds 指定抽取专家ID | |||||
* @param invitedExpertIds 指定抽取专家ID | |||||
* @return 满足抽取条件的专家 | * @return 满足抽取条件的专家 | ||||
* @author WendyYang | * @author WendyYang | ||||
**/ | **/ | ||||
public ExpertChooseDTO expertInviteByRandomRule(AvoidRuleDTO avoidRule, | public ExpertChooseDTO expertInviteByRandomRule(AvoidRuleDTO avoidRule, | ||||
RandomInviteRuleDTO randomRule, | RandomInviteRuleDTO randomRule, | ||||
List<Long> appointExpertIds, | |||||
List<Long> invitedExpertIds, | |||||
LocalDateTime sTime, | LocalDateTime sTime, | ||||
LocalDateTime eTime) { | LocalDateTime eTime) { | ||||
ExpertChooseDTO result = new ExpertChooseDTO(new ArrayList<>(), 0); | ExpertChooseDTO result = new ExpertChooseDTO(new ArrayList<>(), 0); | ||||
@@ -265,17 +298,19 @@ public class ExpertInviteManage { | |||||
} | } | ||||
boolean avoidExpert = CollUtil.isNotEmpty(avoidRule.getExpertIds()); | boolean avoidExpert = CollUtil.isNotEmpty(avoidRule.getExpertIds()); | ||||
boolean avoidCompany = CollUtil.isNotEmpty(avoidRule.getAvoidUnitIdList()); | boolean avoidCompany = CollUtil.isNotEmpty(avoidRule.getAvoidUnitIdList()); | ||||
Set<String> tmpAvoidCompany = new HashSet<>(); | |||||
Set<String> avoidCompanyUniqCodes = new HashSet<>(); | |||||
if (avoidCompany) { | if (avoidCompany) { | ||||
tmpAvoidCompany.addAll(avoidRule.getAvoidUnitIdList()); | |||||
avoidCompanyUniqCodes.addAll(avoidRule.getAvoidUnitIdList()); | |||||
} | |||||
if (CollUtil.isNotEmpty(invitedExpertIds)) { | |||||
List<String> tmpCompanyUniqCodes = expertUserFullInfoService.listCompanyUniqCodeByUserIds(invitedExpertIds); | |||||
avoidCompanyUniqCodes.addAll(tmpCompanyUniqCodes); | |||||
} | } | ||||
// 回避信息 | // 回避信息 | ||||
LambdaQueryWrapper<ExpertUserFullInfo> query = buildBaseExpertQuery(); | LambdaQueryWrapper<ExpertUserFullInfo> query = buildBaseExpertQuery(); | ||||
query.notIn(!tmpAvoidCompany.isEmpty(), ExpertUserFullInfo::getCompanyUniqCode, tmpAvoidCompany); | |||||
if (avoidCompany) { | |||||
query.notExists("select 1 from expert_avoid_company eac where eac.user_id = nd_expert_user_full_info.user_id" + | |||||
" and company_uniq_code in ({0})", CollUtils.joinByComma(avoidRule.getAvoidUnitIdList())); | |||||
} | |||||
query.notIn(!avoidCompanyUniqCodes.isEmpty(), ExpertUserFullInfo::getCompanyUniqCode, avoidCompanyUniqCodes); | |||||
// 处理回避单位与回避条线 | |||||
buildAvoidCompanyAndBusinessStrip(query, avoidRule.getAvoidUnitIdList(), avoidRule.getAvoidOrgIdList()); | |||||
Set<Long> expertIdsIn = new HashSet<>(); | Set<Long> expertIdsIn = new HashSet<>(); | ||||
Set<Long> expertIdsNotIn = new HashSet<>(); | Set<Long> expertIdsNotIn = new HashSet<>(); | ||||
if (CollUtil.isNotEmpty(merge.getExpertIdsIn())) { | if (CollUtil.isNotEmpty(merge.getExpertIdsIn())) { | ||||
@@ -283,6 +318,12 @@ public class ExpertInviteManage { | |||||
} else if (CollUtil.isNotEmpty(merge.getExpertIdsNotIn())) { | } else if (CollUtil.isNotEmpty(merge.getExpertIdsNotIn())) { | ||||
expertIdsNotIn.addAll(merge.getExpertIdsNotIn()); | expertIdsNotIn.addAll(merge.getExpertIdsNotIn()); | ||||
} | } | ||||
// 处理回避专家次数 | |||||
if (avoidRule.getWeekInviteCount() != null) { | |||||
Integer weekInviteCount = avoidRule.getWeekInviteCount(); | |||||
List<Long> tmpExpertIdsNotIn = listAgreedUserIdByRecentMeetings(weekInviteCount, recentDays, sTime); | |||||
expertIdsNotIn.addAll(tmpExpertIdsNotIn); | |||||
} | |||||
// 处理专家层级 | // 处理专家层级 | ||||
addRegionLimit(query, randomRule); | addRegionLimit(query, randomRule); | ||||
if (!expertIdsIn.isEmpty()) { | if (!expertIdsIn.isEmpty()) { | ||||
@@ -293,8 +334,8 @@ public class ExpertInviteManage { | |||||
return result; | return result; | ||||
} | } | ||||
} | } | ||||
if (CollUtil.isNotEmpty(appointExpertIds)) { | |||||
expertIdsIn.removeIf(appointExpertIds::contains); | |||||
if (CollUtil.isNotEmpty(invitedExpertIds)) { | |||||
expertIdsIn.removeIf(invitedExpertIds::contains); | |||||
if (expertIdsIn.isEmpty()) { | if (expertIdsIn.isEmpty()) { | ||||
return result; | return result; | ||||
} | } | ||||
@@ -305,8 +346,8 @@ public class ExpertInviteManage { | |||||
if (expertIdsIn.isEmpty()) { | if (expertIdsIn.isEmpty()) { | ||||
return result; | return result; | ||||
} | } | ||||
} else if (avoidExpert || CollUtil.isNotEmpty(appointExpertIds)) { | |||||
Set<Long> tmpExpert = expertInviteHelper.getAvoidExpert(appointExpertIds, avoidRule, sTime, eTime); | |||||
} else if (avoidExpert || CollUtil.isNotEmpty(invitedExpertIds)) { | |||||
Set<Long> tmpExpert = expertInviteHelper.getAvoidExpert(invitedExpertIds, avoidRule, sTime, eTime); | |||||
expertIdsNotIn.addAll(tmpExpert); | expertIdsNotIn.addAll(tmpExpert); | ||||
} else { | } else { | ||||
Set<Long> tmpNotInUserIds = expertInviteHelper.listExpertLeaveOrInvited(sTime, eTime); | Set<Long> tmpNotInUserIds = expertInviteHelper.listExpertLeaveOrInvited(sTime, eTime); | ||||
@@ -365,8 +406,14 @@ public class ExpertInviteManage { | |||||
LambdaQueryWrapper<ExpertUserFullInfo> query = buildBaseExpertQuery(); | LambdaQueryWrapper<ExpertUserFullInfo> query = buildBaseExpertQuery(); | ||||
// 设置回避单位 | // 设置回避单位 | ||||
Set<String> notInCompanyUniqCodeList = new HashSet<>(avoidRule.getAvoidUnitIdList()); | Set<String> notInCompanyUniqCodeList = new HashSet<>(avoidRule.getAvoidUnitIdList()); | ||||
query.notExists("select 1 from expert_avoid_company eac where eac.user_id = nd_expert_user_full_info.user_id" + | |||||
" and company_uniq_code in ({0})", CollUtils.joinByComma(avoidRule.getAvoidUnitIdList())); | |||||
// 处理回避单位与回避条线 | |||||
buildAvoidCompanyAndBusinessStrip(query, avoidRule.getAvoidUnitIdList(), avoidRule.getAvoidOrgIdList()); | |||||
// 处理回避专家次数 | |||||
if (avoidRule.getWeekInviteCount() != null) { | |||||
Integer weekInviteCount = avoidRule.getWeekInviteCount(); | |||||
List<Long> tmpExpertIdsNotIn = listAgreedUserIdByRecentMeetings(weekInviteCount, recentDays, msTime); | |||||
expertIdsNotIn.addAll(tmpExpertIdsNotIn); | |||||
} | |||||
// 处理专家层级 | // 处理专家层级 | ||||
addRegionLimit(query, randomRule); | addRegionLimit(query, randomRule); | ||||
@@ -403,7 +450,11 @@ public class ExpertInviteManage { | |||||
List<String> tmpUniqCompanyCodes = CollUtils.fieldList(agreeOrNoticingUserInfos, ExpertUserFullInfo::getCompanyUniqCode); | List<String> tmpUniqCompanyCodes = CollUtils.fieldList(agreeOrNoticingUserInfos, ExpertUserFullInfo::getCompanyUniqCode); | ||||
notInCompanyUniqCodeList.addAll(tmpUniqCompanyCodes); | notInCompanyUniqCodeList.addAll(tmpUniqCompanyCodes); | ||||
} | } | ||||
// 已请假的专家不再抽取 | |||||
List<MeetingExpert> expertsOnLeave = expertGroupByStatus.get(ON_LEAVE); | |||||
if (CollUtil.isNotEmpty(expertsOnLeave)) { | |||||
expertIdsNotIn.addAll(CollUtils.fieldList(expertsOnLeave, MeetingExpert::getExpertId)); | |||||
} | |||||
// 处理已拒绝专家与重复抽取 | // 处理已拒绝专家与重复抽取 | ||||
BizUtils.notEmpty(expertGroupByStatus.get(REFUSED), refuseExperts -> { | BizUtils.notEmpty(expertGroupByStatus.get(REFUSED), refuseExperts -> { | ||||
List<Long> tmpExpertIdsNotIn; | List<Long> tmpExpertIdsNotIn; | ||||
@@ -36,6 +36,7 @@ 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.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.MeetingMsgHelper; | |||||
import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; | import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; | ||||
import com.ningdatech.pmapi.meeting.service.*; | import com.ningdatech.pmapi.meeting.service.*; | ||||
import com.ningdatech.pmapi.meeting.task.ExpertInviteTask; | import com.ningdatech.pmapi.meeting.task.ExpertInviteTask; | ||||
@@ -60,6 +61,7 @@ import java.util.function.BiFunction; | |||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
import static com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum.*; | import static com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum.*; | ||||
import static com.ningdatech.pmapi.meeting.entity.enumeration.ExpertInviteTypeEnum.APPOINT; | |||||
import static com.ningdatech.pmapi.meeting.helper.ExpertInviteHelper.getExpertInviteRule; | import static com.ningdatech.pmapi.meeting.helper.ExpertInviteHelper.getExpertInviteRule; | ||||
/** | /** | ||||
@@ -95,6 +97,7 @@ public class MeetingManage { | |||||
private final IDingOrganizationService dingOrganizationService; | private final IDingOrganizationService dingOrganizationService; | ||||
private final IExpertReviewService expertReviewService; | private final IExpertReviewService expertReviewService; | ||||
private final ExpertInviteHelper expertInviteHelper; | private final ExpertInviteHelper expertInviteHelper; | ||||
private final MeetingMsgHelper meetingMsgHelper; | |||||
private static final String INVITED_RULE_CREATE = "INVITED_RULE_CREATE:"; | private static final String INVITED_RULE_CREATE = "INVITED_RULE_CREATE:"; | ||||
private static final String MEETING_CREATE_KEY = "MEETING_CREATE:"; | private static final String MEETING_CREATE_KEY = "MEETING_CREATE:"; | ||||
@@ -199,7 +202,7 @@ public class MeetingManage { | |||||
} | } | ||||
expertInviteTask.cancelByMeetingId(meetingId); | expertInviteTask.cancelByMeetingId(meetingId); | ||||
LambdaUpdateWrapper<Meeting> meetingUpdate = Wrappers.lambdaUpdate(Meeting.class) | LambdaUpdateWrapper<Meeting> meetingUpdate = Wrappers.lambdaUpdate(Meeting.class) | ||||
.set(Meeting::getInviteType, ExpertInviteTypeEnum.APPOINT.getCode()) | |||||
.set(Meeting::getInviteType, APPOINT.getCode()) | |||||
.eq(Meeting::getId, meetingId); | .eq(Meeting::getId, meetingId); | ||||
meetingService.update(meetingUpdate); | meetingService.update(meetingUpdate); | ||||
saveAppointRuleByConvertFromRandomRule(meetingId); | saveAppointRuleByConvertFromRandomRule(meetingId); | ||||
@@ -212,7 +215,7 @@ public class MeetingManage { | |||||
AppointInviteRuleDTO rule = new AppointInviteRuleDTO(); | AppointInviteRuleDTO rule = new AppointInviteRuleDTO(); | ||||
rule.setInviteDesc("转为指定抽取"); | rule.setInviteDesc("转为指定抽取"); | ||||
rule.setExpertIdList(Collections.emptyList()); | rule.setExpertIdList(Collections.emptyList()); | ||||
rule.setInviteType(ExpertInviteTypeEnum.APPOINT.getCode()); | |||||
rule.setInviteType(APPOINT.getCode()); | |||||
rule.setCount(0); | rule.setCount(0); | ||||
ExpertInviteRule inviteRule = new ExpertInviteRule(); | ExpertInviteRule inviteRule = new ExpertInviteRule(); | ||||
inviteRule.setMeetingId(meetingId); | inviteRule.setMeetingId(meetingId); | ||||
@@ -410,6 +413,7 @@ public class MeetingManage { | |||||
Assert.notNull(meeting, "会议不存在"); | Assert.notNull(meeting, "会议不存在"); | ||||
MeetingDetailBasicVO detail = MeetingDetailBasicVO.builder() | MeetingDetailBasicVO detail = MeetingDetailBasicVO.builder() | ||||
.meetingId(meeting.getId()) | .meetingId(meeting.getId()) | ||||
.regionCode(meeting.getRegionCode()) | |||||
.meetingName(meeting.getName()) | .meetingName(meeting.getName()) | ||||
.meetingType(meeting.getType()) | .meetingType(meeting.getType()) | ||||
.meetingAddress(meeting.getMeetingAddress()) | .meetingAddress(meeting.getMeetingAddress()) | ||||
@@ -481,7 +485,7 @@ public class MeetingManage { | |||||
item.setRuleId(me.getRuleId()); | item.setRuleId(me.getRuleId()); | ||||
item.setIsHeadman(me.getIsHeadman()); | item.setIsHeadman(me.getIsHeadman()); | ||||
ExpertInviteRule rule = ruleMap.get(me.getRuleId()); | ExpertInviteRule rule = ruleMap.get(me.getRuleId()); | ||||
item.setInviteType(rule == null ? ExpertInviteTypeEnum.APPOINT.getCode() : rule.getInviteType()); | |||||
item.setInviteType(rule == null ? APPOINT.getCode() : rule.getInviteType()); | |||||
if (NOTICING.eq(me.getStatus())) { | if (NOTICING.eq(me.getStatus())) { | ||||
item.setNoticeStatus("通知中"); | item.setNoticeStatus("通知中"); | ||||
} else { | } else { | ||||
@@ -577,6 +581,7 @@ public class MeetingManage { | |||||
}); | }); | ||||
AvoidRuleDTO avoidInfo = inviteAvoidRuleService.getAvoidInfoDto(meetingId); | AvoidRuleDTO avoidInfo = inviteAvoidRuleService.getAvoidInfoDto(meetingId); | ||||
AvoidInfoVO vo = new AvoidInfoVO(); | AvoidInfoVO vo = new AvoidInfoVO(); | ||||
vo.setWeekInviteCount(avoidInfo.getWeekInviteCount()); | |||||
vo.setAvoidOrgIds(avoidInfo.getAvoidOrgIdList()); | vo.setAvoidOrgIds(avoidInfo.getAvoidOrgIdList()); | ||||
vo.setAvoidUnitIds(avoidInfo.getAvoidUnitIdList()); | vo.setAvoidUnitIds(avoidInfo.getAvoidUnitIdList()); | ||||
if (CollUtil.isNotEmpty(vo.getAvoidOrgIds())) { | if (CollUtil.isNotEmpty(vo.getAvoidOrgIds())) { | ||||
@@ -590,7 +595,7 @@ public class MeetingManage { | |||||
} | } | ||||
result.setAvoidInfo(vo); | result.setAvoidInfo(vo); | ||||
} else { | } else { | ||||
List<ExpertInviteRule> appoints = groupByType.get(ExpertInviteTypeEnum.APPOINT); | |||||
List<ExpertInviteRule> appoints = groupByType.get(APPOINT); | |||||
ExpertInviteRule appoint = appoints.get(0); | ExpertInviteRule appoint = appoints.get(0); | ||||
AppointInviteRuleDTO appointRule = JSON.parseObject(appoint.getInviteRule(), AppointInviteRuleDTO.class); | AppointInviteRuleDTO appointRule = JSON.parseObject(appoint.getInviteRule(), AppointInviteRuleDTO.class); | ||||
appointRule.setId(appoint.getId()); | appointRule.setId(appoint.getId()); | ||||
@@ -610,7 +615,7 @@ public class MeetingManage { | |||||
} | } | ||||
try { | try { | ||||
Meeting meeting = meetingService.getById(meetingId); | Meeting meeting = meetingService.getById(meetingId); | ||||
if (!ExpertInviteTypeEnum.APPOINT.eq(meeting.getInviteType())) { | |||||
if (!APPOINT.eq(meeting.getInviteType())) { | |||||
throw BizException.wrap("该会议不能指定邀请专家"); | throw BizException.wrap("该会议不能指定邀请专家"); | ||||
} | } | ||||
if (meeting.getConfirmedRoster()) { | if (meeting.getConfirmedRoster()) { | ||||
@@ -713,6 +718,37 @@ public class MeetingManage { | |||||
} | } | ||||
} | } | ||||
@Transactional(rollbackFor = Exception.class) | |||||
public void expertRemove(ExpertRemoveReq req) { | |||||
String key = "EXPERT_REMOVE:" + req.getExpertMeetingId(); | |||||
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("会议已取消!"); | |||||
} | |||||
if (LocalDateTime.now().isAfter(meeting.getStartTime())) { | |||||
throw BizException.wrap("会议已开始,不允许移除专家!"); | |||||
} | |||||
MeetingExpert expert = meetingExpertService.getById(req.getExpertMeetingId()); | |||||
if (!APPOINT.eq(expert.getInviteType())) { | |||||
throw BizException.wrap("随机抽取的专家不允许移除!"); | |||||
} | |||||
if (!NOTICING.eq(expert.getStatus())) { | |||||
throw BizException.wrap("已确认过的专家不允许移除!"); | |||||
} | |||||
LambdaUpdateWrapper<Meeting> mUpdate = Wrappers.lambdaUpdate(Meeting.class) | |||||
.set(Meeting::getConfirmedRoster, false) | |||||
.eq(Meeting::getId, req.getMeetingId()); | |||||
meetingService.update(mUpdate); | |||||
meetingExpertService.removeById(req.getExpertMeetingId()); | |||||
} finally { | |||||
distributedLock.releaseLock(key); | |||||
} | |||||
} | |||||
public void releaseExperts(MeetingCancelReq req) { | public void releaseExperts(MeetingCancelReq req) { | ||||
String key = "EXPERT_RELEASE:" + req.getMeetingId(); | String key = "EXPERT_RELEASE:" + req.getMeetingId(); | ||||
if (!distributedLock.lock(key, RETRY_TIMES)) { | if (!distributedLock.lock(key, RETRY_TIMES)) { | ||||
@@ -762,7 +798,8 @@ public class MeetingManage { | |||||
} | } | ||||
} | } | ||||
public void confirmedRoster(Long meetingId) { | |||||
public void confirmedRoster(ConfirmedRosterReq req) { | |||||
Long meetingId = req.getMeetingId(); | |||||
String key = "MEETING_RESEND_SMS:" + meetingId; | String key = "MEETING_RESEND_SMS:" + meetingId; | ||||
if (!distributedLock.lock(key, RETRY_TIMES)) { | if (!distributedLock.lock(key, RETRY_TIMES)) { | ||||
throw BizException.wrap("请刷新后重试!"); | throw BizException.wrap("请刷新后重试!"); | ||||
@@ -780,7 +817,18 @@ public class MeetingManage { | |||||
meetingService.update(update); | meetingService.update(update); | ||||
} | } | ||||
List<MeetingExpert> experts = meetingExpertService.listAgreedExperts(meetingId); | List<MeetingExpert> experts = meetingExpertService.listAgreedExperts(meetingId); | ||||
// TODO 发送会议通知 | |||||
List<MeetingExpert> expertNoticing = experts.stream() | |||||
.filter(w -> meeting.getConfirmedRoster() || !w.getConfirmedRoster()) | |||||
.collect(Collectors.toList()); | |||||
if (expertNoticing.isEmpty()) { | |||||
return; | |||||
} | |||||
List<Long> currConfirmedMeIds = CollUtils.fieldList(expertNoticing, MeetingExpert::getId); | |||||
LambdaUpdateWrapper<MeetingExpert> meUpdate = Wrappers.lambdaUpdate(MeetingExpert.class) | |||||
.in(MeetingExpert::getId, currConfirmedMeIds) | |||||
.set(MeetingExpert::getConfirmedRoster, Boolean.TRUE); | |||||
meetingExpertService.update(meUpdate); | |||||
meetingMsgHelper.sendConfirmedRosterMsg(expertNoticing, meeting); | |||||
} finally { | } finally { | ||||
distributedLock.releaseLock(key); | distributedLock.releaseLock(key); | ||||
} | } | ||||
@@ -9,6 +9,7 @@ import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | |||||
import com.ningdatech.pmapi.meeting.entity.req.ReviewProjectListReq; | import com.ningdatech.pmapi.meeting.entity.req.ReviewProjectListReq; | ||||
import org.apache.ibatis.annotations.Param; | import org.apache.ibatis.annotations.Param; | ||||
import java.time.LocalDateTime; | |||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -62,6 +63,19 @@ public interface MeetingExpertMapper extends BaseMapper<MeetingExpert> { | |||||
@Param("meetingIds") Collection<Long> meetingIds); | @Param("meetingIds") Collection<Long> meetingIds); | ||||
/** | /** | ||||
* 查询时间窗口之内参与会议不超过{@code agreeCount}次的专家ID | |||||
* | |||||
* @param agreeCount 参与次数(包含) | |||||
* @param startTime 开始时间 | |||||
* @param endTime 结束时间 | |||||
* @return 专家ID集合 | |||||
* @author WendyYang | |||||
**/ | |||||
List<Long> listAgreeExpertIdByRecentDaysAndAgreeCount(@Param("agreeCount") Integer agreeCount, | |||||
@Param("startTime") LocalDateTime startTime, | |||||
@Param("endTime") LocalDateTime endTime); | |||||
/** | |||||
* 根据会议ID与参与状态统计专家数量 | * 根据会议ID与参与状态统计专家数量 | ||||
* | * | ||||
* @param status 会议状态 | * @param status 会议状态 | ||||
@@ -50,6 +50,15 @@ | |||||
</if> | </if> | ||||
</select> | </select> | ||||
<select id="listAgreeExpertIdByRecentDaysAndAgreeCount" resultType="long"> | |||||
SELECT expert_id FROM (SELECT ROW_NUMBER() OVER ( PARTITION BY expert_id, meeting_id ORDER BY update_on DESC ) | |||||
rowNumber,expert_id, status FROM meeting_expert | |||||
where meeting_id in (select id from meeting m where m.status = 1 | |||||
and ((m.start_time >= #{startTime} and m.start_time < #{endTime}) | |||||
or (m.end_time >= #{startTime} and m.end_time < #{endTime})) )) em | |||||
WHERE rowNumber = 1 and status = 3 group by expert_id having count(1) >= #{agreeCount} | |||||
</select> | |||||
<select id="countExpertByStatusAndMeetingId" | <select id="countExpertByStatusAndMeetingId" | ||||
resultType="int"> | resultType="int"> | ||||
SELECT count(1) FROM (SELECT ROW_NUMBER() OVER ( PARTITION BY expert_id, meeting_id ORDER BY update_on DESC ) | SELECT count(1) FROM (SELECT ROW_NUMBER() OVER ( PARTITION BY expert_id, meeting_id ORDER BY update_on DESC ) | ||||
@@ -9,8 +9,8 @@ import com.ningdatech.pmapi.meeting.entity.dto.ReviewProjectDTO; | |||||
import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | ||||
import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertInviteTypeEnum; | import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertInviteTypeEnum; | ||||
import com.ningdatech.pmapi.meeting.entity.req.ReviewProjectListReq; | import com.ningdatech.pmapi.meeting.entity.req.ReviewProjectListReq; | ||||
import org.apache.ibatis.annotations.Param; | |||||
import java.time.LocalDateTime; | |||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -155,4 +155,6 @@ public interface IMeetingExpertService extends IService<MeetingExpert> { | |||||
**/ | **/ | ||||
Page<ReviewProjectDTO> pageReviewProjectList(ReviewProjectListReq req); | Page<ReviewProjectDTO> pageReviewProjectList(ReviewProjectListReq req); | ||||
List<Long> listAgreeExpertIdByRecentDaysAndAgreeCount(int agreeCount, LocalDateTime sTime, LocalDateTime eTime); | |||||
} | } |
@@ -24,4 +24,13 @@ public interface IMeetingInnerProjectService extends IService<MeetingInnerProjec | |||||
**/ | **/ | ||||
List<MeetingInnerProject> listByMeetingId(Long meetingId); | List<MeetingInnerProject> listByMeetingId(Long meetingId); | ||||
/** | |||||
* 查询项目关联的所有会议 | |||||
* | |||||
* @param projectId 会议ID | |||||
* @return 项目关联的会议ID | |||||
* @author WendyYang | |||||
**/ | |||||
List<Long> listMeetingIdByProjectId(Long projectId); | |||||
} | } |
@@ -39,7 +39,7 @@ public class ExpertInviteAvoidRuleServiceImpl extends ServiceImpl<ExpertInviteAv | |||||
avoidInfo.setAvoidOrgIdList(StrUtils.split(avoidRule.getAvoidOrgIds())); | avoidInfo.setAvoidOrgIdList(StrUtils.split(avoidRule.getAvoidOrgIds())); | ||||
avoidInfo.setAvoidUnitIdList(StrUtils.split(avoidRule.getAvoidUnitIds())); | avoidInfo.setAvoidUnitIdList(StrUtils.split(avoidRule.getAvoidUnitIds())); | ||||
avoidInfo.setExpertIds(BizUtils.splitToLong(avoidRule.getAvoidExpertIds())); | avoidInfo.setExpertIds(BizUtils.splitToLong(avoidRule.getAvoidExpertIds())); | ||||
avoidInfo.setWeekInviteCount(avoidInfo.getWeekInviteCount()); | |||||
avoidInfo.setWeekInviteCount(avoidRule.getWeekInviteCount()); | |||||
return avoidInfo; | return avoidInfo; | ||||
} | } | ||||
@@ -19,6 +19,7 @@ import com.ningdatech.pmapi.meeting.service.IMeetingExpertService; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import java.time.LocalDateTime; | |||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
@@ -134,4 +135,9 @@ public class MeetingExpertServiceImpl extends ServiceImpl<MeetingExpertMapper, M | |||||
return baseMapper.pageReviewProjectList(req.page(), req); | return baseMapper.pageReviewProjectList(req.page(), req); | ||||
} | } | ||||
@Override | |||||
public List<Long> listAgreeExpertIdByRecentDaysAndAgreeCount(int agreeCount, LocalDateTime sTime, LocalDateTime eTime) { | |||||
return baseMapper.listAgreeExpertIdByRecentDaysAndAgreeCount(agreeCount, sTime, eTime); | |||||
} | |||||
} | } |
@@ -1,7 +1,9 @@ | |||||
package com.ningdatech.pmapi.meeting.service.impl; | package com.ningdatech.pmapi.meeting.service.impl; | ||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.ningdatech.pmapi.meeting.entity.domain.MeetingInnerProject; | import com.ningdatech.pmapi.meeting.entity.domain.MeetingInnerProject; | ||||
import com.ningdatech.pmapi.meeting.mapper.MeetingInnerProjectMapper; | import com.ningdatech.pmapi.meeting.mapper.MeetingInnerProjectMapper; | ||||
import com.ningdatech.pmapi.meeting.service.IMeetingInnerProjectService; | import com.ningdatech.pmapi.meeting.service.IMeetingInnerProjectService; | ||||
@@ -26,4 +28,12 @@ public class MeetingInnerProjectServiceImpl extends ServiceImpl<MeetingInnerProj | |||||
.eq(MeetingInnerProject::getMeetingId, meetingId)); | .eq(MeetingInnerProject::getMeetingId, meetingId)); | ||||
} | } | ||||
@Override | |||||
public List<Long> listMeetingIdByProjectId(Long projectId) { | |||||
LambdaQueryWrapper<MeetingInnerProject> query = Wrappers | |||||
.lambdaQuery(MeetingInnerProject.class) | |||||
.eq(MeetingInnerProject::getProjectId, projectId); | |||||
return CollUtils.fieldList(list(query), MeetingInnerProject::getMeetingId); | |||||
} | |||||
} | } |
@@ -207,7 +207,7 @@ public class ExpertCallResultRewriteTask { | |||||
status = REFUSED; | status = REFUSED; | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("获取电话回调结果异常", e); | |||||
log.error("获取电话回调结果异常{}", mrd, e); | |||||
status = UNANSWERED; | status = UNANSWERED; | ||||
} | } | ||||
} else { | } else { | ||||
@@ -16,6 +16,7 @@ import com.ningdatech.pmapi.meeting.entity.dto.ExpertChooseDTO; | |||||
import com.ningdatech.pmapi.meeting.entity.dto.InviteCacheDTO; | import com.ningdatech.pmapi.meeting.entity.dto.InviteCacheDTO; | ||||
import com.ningdatech.pmapi.meeting.entity.dto.RandomInviteRuleDTO; | import com.ningdatech.pmapi.meeting.entity.dto.RandomInviteRuleDTO; | ||||
import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatusEnum; | ||||
import com.ningdatech.pmapi.meeting.helper.MeetingMsgHelper; | |||||
import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; | import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; | ||||
import com.ningdatech.pmapi.meeting.manage.ExpertInviteManage; | import com.ningdatech.pmapi.meeting.manage.ExpertInviteManage; | ||||
import com.ningdatech.pmapi.meeting.service.IExpertInviteAvoidRuleService; | import com.ningdatech.pmapi.meeting.service.IExpertInviteAvoidRuleService; | ||||
@@ -74,6 +75,7 @@ public class ExpertInviteTask { | |||||
private final ExpertInviteManage expertInviteManage; | private final ExpertInviteManage expertInviteManage; | ||||
private final IExpertInviteAvoidRuleService inviteAvoidRuleService; | private final IExpertInviteAvoidRuleService inviteAvoidRuleService; | ||||
private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | ||||
private final MeetingMsgHelper meetingMsgHelper; | |||||
/** | /** | ||||
* 用来存入线程执行句柄, 停止定时任务时使用 | * 用来存入线程执行句柄, 停止定时任务时使用 | ||||
@@ -273,6 +275,7 @@ public class ExpertInviteTask { | |||||
if (notIgnoreCnt.get() == 0 || notIgnoreCnt.get() == notSupportCnt.get()) { | if (notIgnoreCnt.get() == 0 || notIgnoreCnt.get() == notSupportCnt.get()) { | ||||
log.info("停止会议随机邀请:{} 未完成抽取规则数量 {} 无可抽取专家规则数量 {}", meetingId, notIgnoreCnt, notSupportCnt); | log.info("停止会议随机邀请:{} 未完成抽取规则数量 {} 无可抽取专家规则数量 {}", meetingId, notIgnoreCnt, notSupportCnt); | ||||
currProxy().cancelByMeetingId(meetingId); | currProxy().cancelByMeetingId(meetingId); | ||||
meetingMsgHelper.sendInviteStopMsg(meeting.getCreateBy(), meetingId, meeting.getName()); | |||||
} | } | ||||
} | } | ||||
@@ -42,4 +42,10 @@ public class RandomInviteProperties { | |||||
* 近期会议数量(以此来降低专家抽中间隔) | * 近期会议数量(以此来降低专家抽中间隔) | ||||
*/ | */ | ||||
private Integer recentMeetingCount = 5; | private Integer recentMeetingCount = 5; | ||||
/** | |||||
* 参会次数限制天数 | |||||
*/ | |||||
private Integer recentDays = 7; | |||||
} | } |
@@ -28,6 +28,9 @@ import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | |||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||||
import com.ningdatech.pmapi.sys.manage.NoticeManage; | |||||
import com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant; | |||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import com.wflow.bean.entity.WflowModels; | import com.wflow.bean.entity.WflowModels; | ||||
@@ -80,6 +83,8 @@ public class ConstructionPlanManage { | |||||
private final DefaultDeclaredProjectManage declaredProjectManage; | private final DefaultDeclaredProjectManage declaredProjectManage; | ||||
private final DefaultDeclaredProjectManage defaultDeclaredProjectManage; | private final DefaultDeclaredProjectManage defaultDeclaredProjectManage; | ||||
private final NoticeManage noticeManage; | |||||
/** | /** | ||||
* 建设方案 | * 建设方案 | ||||
* | * | ||||
@@ -133,6 +138,10 @@ public class ConstructionPlanManage { | |||||
//保存建设项目 | //保存建设项目 | ||||
modifyProject(projectInfo, instanceId, projectInfo.getConstructionPlanFile()); | modifyProject(projectInfo, instanceId, projectInfo.getConstructionPlanFile()); | ||||
//发送给第一个审批人消息 | |||||
noticeManage.sendFirtUser(projectInfo,model.getFormName(),instanceId, | |||||
WorkNoticeContant.PASS_MSG_TEMPLATE, MsgTypeEnum.PROJECT_REVIEW); | |||||
return instanceId; | return instanceId; | ||||
} | } | ||||
@@ -154,8 +163,9 @@ public class ConstructionPlanManage { | |||||
VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); | VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); | ||||
VUtils.isTrue(StringUtils.isBlank(projectDto.getConstructionPlanFile())).throwMessage("提交失败 请提交建设方案!"); | VUtils.isTrue(StringUtils.isBlank(projectDto.getConstructionPlanFile())).throwMessage("提交失败 请提交建设方案!"); | ||||
//直接先到待方案审批 | //直接先到待方案审批 | ||||
projectInfo.setStatus(ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode()); | |||||
projectService.updateById(projectInfo); | |||||
Project project = projectLibManage.saveProjectWithVersionAndStatus(projectDto,null, | |||||
ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode()); | |||||
dto.getProjectInfo().setId(project.getId()); | |||||
return startTheProcess(dto); | return startTheProcess(dto); | ||||
} | } | ||||
@@ -11,7 +11,7 @@ import com.ningdatech.basic.function.VUtils; | |||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
import com.ningdatech.basic.util.CollUtils; | import com.ningdatech.basic.util.CollUtils; | ||||
import com.ningdatech.basic.util.NdDateUtils; | import com.ningdatech.basic.util.NdDateUtils; | ||||
import com.ningdatech.pmapi.common.constant.CommonConst; | |||||
import com.ningdatech.pmapi.common.constant.BizConst; | |||||
import com.ningdatech.pmapi.common.constant.RegionConst; | import com.ningdatech.pmapi.common.constant.RegionConst; | ||||
import com.ningdatech.pmapi.common.enumeration.CommonEnum; | import com.ningdatech.pmapi.common.enumeration.CommonEnum; | ||||
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | ||||
@@ -19,44 +19,35 @@ import com.ningdatech.pmapi.common.helper.RegionCacheHelper; | |||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | import com.ningdatech.pmapi.common.helper.UserInfoHelper; | ||||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | import com.ningdatech.pmapi.common.util.ExcelDownUtil; | ||||
import com.ningdatech.pmapi.common.util.ExcelExportStyle; | import com.ningdatech.pmapi.common.util.ExcelExportStyle; | ||||
import com.ningdatech.pmapi.organization.model.entity.DingOrganization; | |||||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||||
import com.ningdatech.pmapi.projectdeclared.model.dto.*; | import com.ningdatech.pmapi.projectdeclared.model.dto.*; | ||||
import com.ningdatech.pmapi.projectdeclared.model.entity.ProjectDraft; | import com.ningdatech.pmapi.projectdeclared.model.entity.ProjectDraft; | ||||
import com.ningdatech.pmapi.projectdeclared.model.vo.ProjectDraftVO; | import com.ningdatech.pmapi.projectdeclared.model.vo.ProjectDraftVO; | ||||
import com.ningdatech.pmapi.projectdeclared.service.IProjectDraftService; | import com.ningdatech.pmapi.projectdeclared.service.IProjectDraftService; | ||||
import com.ningdatech.pmapi.projectdeclared.utils.GenerateProjectCodeUtil; | import com.ningdatech.pmapi.projectdeclared.utils.GenerateProjectCodeUtil; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectRenewalApprovalStatusEnum; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; | ||||
import com.ningdatech.pmapi.projectlib.helper.ProjectHelper; | import com.ningdatech.pmapi.projectlib.helper.ProjectHelper; | ||||
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | ||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | ||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectRenewalExportDTO; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | ||||
import com.ningdatech.pmapi.projectlib.model.po.ProjectRenewalFundDeclarationPO; | |||||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | ||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||||
import com.ningdatech.pmapi.sys.manage.NoticeManage; | |||||
import com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant; | |||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import com.wflow.bean.entity.WflowModels; | import com.wflow.bean.entity.WflowModels; | ||||
import com.wflow.bean.entity.WflowOrgModels; | |||||
import com.wflow.enums.OrgTypeEnum; | |||||
import com.wflow.enums.ProcessDefTypeEnum; | |||||
import com.wflow.exception.BusinessException; | import com.wflow.exception.BusinessException; | ||||
import com.wflow.service.OrgProcdefService; | |||||
import com.wflow.workflow.bean.dto.OrgInfoDTO; | import com.wflow.workflow.bean.dto.OrgInfoDTO; | ||||
import com.wflow.workflow.bean.vo.ProcessStartParamsVo; | import com.wflow.workflow.bean.vo.ProcessStartParamsVo; | ||||
import com.wflow.workflow.service.ProcessInstanceService; | import com.wflow.workflow.service.ProcessInstanceService; | ||||
import com.wflow.workflow.service.ProcessModelService; | import com.wflow.workflow.service.ProcessModelService; | ||||
import lombok.AllArgsConstructor; | |||||
import lombok.NoArgsConstructor; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
@@ -84,7 +75,7 @@ public class DeclaredProjectManage { | |||||
private final IProjectService projectService; | private final IProjectService projectService; | ||||
private final IProjectApplicationService projectApplicationService; | |||||
private final ProjectLibManage projectLibManage; | |||||
private final IProjectDraftService projectDraftService; | private final IProjectDraftService projectDraftService; | ||||
@@ -92,16 +83,13 @@ public class DeclaredProjectManage { | |||||
private final ProcessModelService processModelService; | private final ProcessModelService processModelService; | ||||
private final IProjectInstService projectInstService; | |||||
private final DefaultDeclaredProjectManage defaultDeclaredProjectManage; | private final DefaultDeclaredProjectManage defaultDeclaredProjectManage; | ||||
private final ProjectLibManage projectlibManager; | |||||
private final NoticeManage noticeManage; | |||||
private final UserInfoHelper userInfoHelper; | private final UserInfoHelper userInfoHelper; | ||||
private final RegionCacheHelper regionCacheHelper; | private final RegionCacheHelper regionCacheHelper; | ||||
private final GenerateProjectCodeUtil generateProjectCodeUtil; | |||||
/** | /** | ||||
* 新项目 启动实例 | * 新项目 启动实例 | ||||
@@ -142,12 +130,14 @@ public class DeclaredProjectManage { | |||||
projectInfo.setId(null); | projectInfo.setId(null); | ||||
} | } | ||||
// defaultDeclaredProjectManage.startProcess(projectInfo,user,ProjectProcessStageEnum.ORG_INTERNAL_APPROVAL_PROCESS.getCode()); | |||||
String regionCode = user.getRegionCode(); | String regionCode = user.getRegionCode(); | ||||
WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) | WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) | ||||
.eq(WflowModels::getRegionCode, regionCode) | .eq(WflowModels::getRegionCode, regionCode) | ||||
.eq(WflowModels::getProcessType, ProjectProcessStageEnum.ORG_INTERNAL_APPROVAL_PROCESS.getCode()) | .eq(WflowModels::getProcessType, ProjectProcessStageEnum.ORG_INTERNAL_APPROVAL_PROCESS.getCode()) | ||||
.last("limit 1")); | |||||
.last(BizConst.LIMIT_1)); | |||||
if (Objects.isNull(model)) { | if (Objects.isNull(model)) { | ||||
log.error("此 【{}】区域找不到单位流程配置", regionCode); | log.error("此 【{}】区域找不到单位流程配置", regionCode); | ||||
@@ -174,11 +164,17 @@ public class DeclaredProjectManage { | |||||
log.info("申报项目成功 【{}】", instanceId); | log.info("申报项目成功 【{}】", instanceId); | ||||
//如果是重新提交的话 判断下 项目是否存在 | //如果是重新提交的话 判断下 项目是否存在 | ||||
if(saveOrUpdateProject(projectInfo, instanceId,employeeCode) && Objects.nonNull(projectInfo.getDraftId())){ | |||||
//保存项目相关 | |||||
Project buildProject = projectLibManage.saveProjectInDeclared(projectInfo,instanceId,employeeCode); | |||||
if(Objects.nonNull(projectInfo.getDraftId())){ | |||||
//如果是草稿箱提交 删除对应的草稿箱 | //如果是草稿箱提交 删除对应的草稿箱 | ||||
projectDraftService.removeById(projectInfo.getDraftId()); | projectDraftService.removeById(projectInfo.getDraftId()); | ||||
} | } | ||||
//发送给第一个审批人消息 | |||||
noticeManage.sendFirtUser(buildProject,model.getFormName(),instanceId, | |||||
WorkNoticeContant.PASS_MSG_TEMPLATE, MsgTypeEnum.PROJECT_REVIEW); | |||||
return instanceId; | return instanceId; | ||||
} | } | ||||
@@ -206,7 +202,10 @@ public class DeclaredProjectManage { | |||||
VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); | VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); | ||||
//项目名称去重 | //项目名称去重 | ||||
defaultDeclaredProjectManage.checkDuplication(projectDto); | |||||
if(StringUtils.isNotBlank(projectDto.getProjectName()) && | |||||
!projectDto.getProjectName().equals(projectInfo.getProjectName())){ | |||||
defaultDeclaredProjectManage.checkDuplication(projectDto); | |||||
} | |||||
//判断申报金额 是否等于总的 判断年度支付金额 是否等于总金额 | //判断申报金额 是否等于总的 判断年度支付金额 是否等于总金额 | ||||
defaultDeclaredProjectManage.checkAmount(projectDto); | defaultDeclaredProjectManage.checkAmount(projectDto); | ||||
@@ -240,62 +239,14 @@ public class DeclaredProjectManage { | |||||
String instanceId = processService.newStartProcess(model.getProcessDefId(),model.getFormId(), params,orgModelMap); | String instanceId = processService.newStartProcess(model.getProcessDefId(),model.getFormId(), params,orgModelMap); | ||||
log.info("重新申报项目成功 【{}】", instanceId); | log.info("重新申报项目成功 【{}】", instanceId); | ||||
//保存项目 | |||||
saveOrUpdateProject(projectDto,instanceId,employeeCode); | |||||
//保存项目相关 | |||||
Project buildProject = projectLibManage.saveProjectInDeclared(projectDto,instanceId,employeeCode); | |||||
return instanceId; | |||||
} | |||||
//发送给第一个审批人消息 | |||||
noticeManage.sendFirtUser(buildProject,model.getFormName(),instanceId, | |||||
WorkNoticeContant.PASS_MSG_TEMPLATE, MsgTypeEnum.PROJECT_REVIEW); | |||||
/** | |||||
* 申报项目 时 新增项目到项目库 | |||||
* | |||||
* @param projectDto | |||||
* @param instanceId | |||||
*/ | |||||
private Boolean saveOrUpdateProject(ProjectDTO projectDto, String instanceId, | |||||
String employeeCode) { | |||||
//流程启动之后 入库项目 重要业务信息 用于列表查询 展示 | |||||
try { | |||||
//保存项目表信息 | |||||
Project project = new Project(); | |||||
BeanUtils.copyProperties(projectDto, project); | |||||
project.setCreateOn(LocalDateTime.now()); | |||||
project.setUpdateOn(LocalDateTime.now()); | |||||
project.setStage(ProjectStatusEnum.NOT_APPROVED.getCode()); | |||||
project.setStatus(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode()); | |||||
project.setInstCode(instanceId); | |||||
project.setSponsor(employeeCode); | |||||
String projectCode = generateProjectCodeUtil.generateProjectCode(projectDto); | |||||
project.setProjectCode(projectCode); | |||||
projectService.saveOrUpdate(project); | |||||
//保存项目应用 | |||||
Boolean isApp = Objects.nonNull(projectDto.getIncludeApplication()) && 1 == projectDto.getIncludeApplication() | |||||
? Boolean.TRUE : Boolean.FALSE; | |||||
//采取批量删除 批量添加的方式 | |||||
projectApplicationService.remove(Wrappers.lambdaQuery(ProjectApplication.class) | |||||
.eq(ProjectApplication::getProjectId,project.getId())); | |||||
if (isApp && CollUtil.isNotEmpty(projectDto.getApplicationList())) { | |||||
List<ProjectApplication> applications = projectDto.getApplicationList().stream().map(application -> { | |||||
ProjectApplication projectApplication = new ProjectApplication(); | |||||
BeanUtils.copyProperties(application, projectApplication); | |||||
projectApplication.setProjectId(project.getId()); | |||||
return projectApplication; | |||||
}).collect(Collectors.toList()); | |||||
projectApplicationService.saveOrUpdateBatch(applications); | |||||
} | |||||
//保存项目和实例的关系 | |||||
ProjectInst projectInst = new ProjectInst(); | |||||
projectInst.setProjectId(project.getId()); | |||||
projectInst.setInstCode(instanceId); | |||||
projectInst.setCreatOn(LocalDateTime.now()); | |||||
projectInst.setUpdateOn(LocalDateTime.now()); | |||||
projectInst.setInstType(ProjectProcessStageEnum.ORG_INTERNAL_APPROVAL_PROCESS.getCode()); | |||||
projectInstService.save(projectInst); | |||||
} catch (Exception e) { | |||||
log.error("项目信息入库错误 " + e); | |||||
throw new BusinessException("项目信息入库错误 :" + e); | |||||
} | |||||
return Boolean.TRUE; | |||||
return instanceId; | |||||
} | } | ||||
public PageVo<ProjectDraftVO> pageDraft(DeclaredProjectListParamDTO params) { | public PageVo<ProjectDraftVO> pageDraft(DeclaredProjectListParamDTO params) { | ||||
@@ -382,6 +333,7 @@ public class DeclaredProjectManage { | |||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | ||||
//当非预审申报的时候 是自己单位 当是预审申报的时候 要主管单位 | //当非预审申报的时候 是自己单位 当是预审申报的时候 要主管单位 | ||||
preQuery(query,user); | preQuery(query,user); | ||||
query.eq(Project::getNewest,Boolean.TRUE); | |||||
Page<Project> page = projectService.page(req.page(), query); | Page<Project> page = projectService.page(req.page(), query); | ||||
long total; | long total; | ||||
if ((total = page.getTotal()) == 0) { | if ((total = page.getTotal()) == 0) { | ||||
@@ -426,6 +378,7 @@ public class DeclaredProjectManage { | |||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | ||||
//当非预审申报的时候 是自己单位 当是预审申报的时候 要主管单位 | //当非预审申报的时候 是自己单位 当是预审申报的时候 要主管单位 | ||||
preQuery(query,user); | preQuery(query,user); | ||||
query.eq(Project::getNewest,Boolean.TRUE); | |||||
List<Project> records = projectService.list(query); | List<Project> records = projectService.list(query); | ||||
AtomicInteger serialNumber = new AtomicInteger(0); | AtomicInteger serialNumber = new AtomicInteger(0); | ||||
@@ -3,11 +3,12 @@ package com.ningdatech.pmapi.projectdeclared.manage; | |||||
import com.alibaba.fastjson.JSON; | import com.alibaba.fastjson.JSON; | ||||
import com.alibaba.fastjson.TypeReference; | import com.alibaba.fastjson.TypeReference; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.google.common.collect.Maps; | |||||
import com.ningdatech.basic.function.VUtils; | import com.ningdatech.basic.function.VUtils; | ||||
import com.ningdatech.pmapi.common.constant.BizConst; | |||||
import com.ningdatech.pmapi.common.constant.RegionConst; | import com.ningdatech.pmapi.common.constant.RegionConst; | ||||
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | |||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | import com.ningdatech.pmapi.common.helper.UserInfoHelper; | ||||
import com.ningdatech.pmapi.organization.model.entity.DingOrganization; | |||||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||||
import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | ||||
import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectConditionDTO; | import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectConditionDTO; | ||||
import com.ningdatech.pmapi.projectdeclared.model.po.DeclaredProjectStatisticsPO; | import com.ningdatech.pmapi.projectdeclared.model.po.DeclaredProjectStatisticsPO; | ||||
@@ -17,13 +18,16 @@ 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.user.security.auth.model.UserFullInfoDTO; | import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import com.wflow.bean.entity.WflowModels; | |||||
import com.wflow.bean.entity.WflowOrgModels; | import com.wflow.bean.entity.WflowOrgModels; | ||||
import com.wflow.enums.OrgTypeEnum; | import com.wflow.enums.OrgTypeEnum; | ||||
import com.wflow.enums.ProcessDefTypeEnum; | import com.wflow.enums.ProcessDefTypeEnum; | ||||
import com.wflow.exception.BusinessException; | |||||
import com.wflow.service.OrgProcdefService; | import com.wflow.service.OrgProcdefService; | ||||
import com.wflow.workflow.bean.dto.OrgInfoDTO; | import com.wflow.workflow.bean.dto.OrgInfoDTO; | ||||
import com.wflow.workflow.bean.dto.ProcessInstanceUserDto; | import com.wflow.workflow.bean.dto.ProcessInstanceUserDto; | ||||
import com.wflow.workflow.bean.vo.ProcessStartParamsVo; | import com.wflow.workflow.bean.vo.ProcessStartParamsVo; | ||||
import com.wflow.workflow.service.ProcessModelService; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.springframework.beans.BeanUtils; | import org.springframework.beans.BeanUtils; | ||||
@@ -48,11 +52,40 @@ public class DefaultDeclaredProjectManage { | |||||
private final UserInfoHelper userInfoHelper; | private final UserInfoHelper userInfoHelper; | ||||
private final IDingOrganizationService dingOrganizationService; | |||||
private final ProcessModelService processModelService; | |||||
private final OrgProcdefService orgProcdefService; | private final OrgProcdefService orgProcdefService; | ||||
private final IDeclaredStatisticsService statisticsService; | private final IDeclaredStatisticsService statisticsService; | ||||
/** | |||||
* 公共的发起流程方法 | |||||
*/ | |||||
public void startProcess(ProjectDTO projectDTO,UserFullInfoDTO user,Integer processType){ | |||||
WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) | |||||
.eq(WflowModels::getRegionCode, user.getRegionCode()) | |||||
.eq(WflowModels::getProcessType, processType) | |||||
.last(BizConst.LIMIT_1)); | |||||
if (Objects.isNull(model)) { | |||||
log.error("此 【{}】区域找不到对应流程配置", user.getRegionCode()); | |||||
throw new BusinessException(String.format("此 【%s】区域找不到对应流程配置", user.getRegionCode())); | |||||
} | |||||
ProcessStartParamsVo params = new ProcessStartParamsVo(); | |||||
params.setUser(buildUser(user.getEmployeeCode())); | |||||
params.setProcessUsers(Collections.emptyMap()); | |||||
//放入条件判断的项目字段 | |||||
ProjectConditionDTO conditionDto = new ProjectConditionDTO(); | |||||
BeanUtils.copyProperties(projectDTO, conditionDto); | |||||
Map<String,Object> formData = Maps.newHashMap(); | |||||
formData.putAll( | |||||
JSON.parseObject(JSON.toJSONString(conditionDto), new TypeReference<Map<String, Object>>() { | |||||
}) | |||||
); | |||||
params.setFormData(formData); | |||||
} | |||||
//项目名称去重 | //项目名称去重 | ||||
public void checkDuplication(ProjectDTO project){ | public void checkDuplication(ProjectDTO project){ | ||||
VUtils.isTrue(projectService.count(Wrappers.lambdaQuery(Project.class) | VUtils.isTrue(projectService.count(Wrappers.lambdaQuery(Project.class) | ||||
@@ -1,9 +1,6 @@ | |||||
package com.ningdatech.pmapi.projectdeclared.manage; | package com.ningdatech.pmapi.projectdeclared.manage; | ||||
import cn.hutool.core.collection.CollUtil; | |||||
import com.alibaba.excel.EasyExcel; | import com.alibaba.excel.EasyExcel; | ||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.TypeReference; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
@@ -12,16 +9,14 @@ import com.ningdatech.basic.function.VUtils; | |||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
import com.ningdatech.basic.util.CollUtils; | import com.ningdatech.basic.util.CollUtils; | ||||
import com.ningdatech.basic.util.NdDateUtils; | import com.ningdatech.basic.util.NdDateUtils; | ||||
import com.ningdatech.pmapi.common.constant.BizConst; | |||||
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | ||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | import com.ningdatech.pmapi.common.helper.UserInfoHelper; | ||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | ||||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | import com.ningdatech.pmapi.common.util.ExcelDownUtil; | ||||
import com.ningdatech.pmapi.common.util.ExcelExportStyle; | import com.ningdatech.pmapi.common.util.ExcelExportStyle; | ||||
import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | |||||
import com.ningdatech.pmapi.datascope.utils.DataScopeUtil; | |||||
import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | ||||
import com.ningdatech.pmapi.projectdeclared.model.dto.PretrialDeclaredExportDTO; | import com.ningdatech.pmapi.projectdeclared.model.dto.PretrialDeclaredExportDTO; | ||||
import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectConditionDTO; | |||||
import com.ningdatech.pmapi.projectdeclared.model.req.PrequalificationDeclaredListReq; | import com.ningdatech.pmapi.projectdeclared.model.req.PrequalificationDeclaredListReq; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; | ||||
@@ -34,8 +29,11 @@ import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | |||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||||
import com.ningdatech.pmapi.staging.service.IProjectStagingService; | import com.ningdatech.pmapi.staging.service.IProjectStagingService; | ||||
import com.ningdatech.pmapi.sys.manage.NoticeManage; | |||||
import com.ningdatech.pmapi.todocenter.constant.TodoCenterContant; | import com.ningdatech.pmapi.todocenter.constant.TodoCenterContant; | ||||
import com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant; | |||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import com.wflow.bean.entity.WflowModels; | import com.wflow.bean.entity.WflowModels; | ||||
@@ -69,6 +67,8 @@ public class PrequalificationDeclaredProjectManage { | |||||
private final IProjectService projectService; | private final IProjectService projectService; | ||||
private final ProjectLibManage projectLibManage; | |||||
private final StateMachineUtils stateMachineUtils; | private final StateMachineUtils stateMachineUtils; | ||||
private final IProjectStagingService projectStagingService; | private final IProjectStagingService projectStagingService; | ||||
@@ -83,6 +83,8 @@ public class PrequalificationDeclaredProjectManage { | |||||
private final IProjectInstService projectInstService; | private final IProjectInstService projectInstService; | ||||
private final NoticeManage noticeManage; | |||||
/** | /** | ||||
* 提交预审 | * 提交预审 | ||||
* @param dto | * @param dto | ||||
@@ -158,9 +160,10 @@ public class PrequalificationDeclaredProjectManage { | |||||
VUtils.isTrue(Objects.isNull(projectDto.getId())).throwMessage("提交失败 缺少项目ID!"); | VUtils.isTrue(Objects.isNull(projectDto.getId())).throwMessage("提交失败 缺少项目ID!"); | ||||
Project projectInfo = projectService.getById(projectDto.getId()); | Project projectInfo = projectService.getById(projectDto.getId()); | ||||
VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); | VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); | ||||
//先回到 待预审状态 | |||||
projectInfo.setStatus(ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode()); | |||||
projectService.updateById(projectInfo); | |||||
//重新提交 生成新版本号 回到 待预审状态 | |||||
Project project = projectLibManage.saveProjectWithVersionAndStatus(projectDto,null, | |||||
ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode()); | |||||
dto.getProjectInfo().setId(project.getId()); | |||||
return startTheProcess(dto); | return startTheProcess(dto); | ||||
} | } | ||||
@@ -181,7 +184,7 @@ public class PrequalificationDeclaredProjectManage { | |||||
WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) | WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) | ||||
.eq(WflowModels::getRegionCode, regionCode) | .eq(WflowModels::getRegionCode, regionCode) | ||||
.eq(WflowModels::getProcessType, ProjectProcessStageEnum.PROJECT_PREQUALIFICATION_APPROVAL_PROCESS.getCode()) | .eq(WflowModels::getProcessType, ProjectProcessStageEnum.PROJECT_PREQUALIFICATION_APPROVAL_PROCESS.getCode()) | ||||
.last("limit 1")); | |||||
.last(BizConst.LIMIT_1)); | |||||
if (Objects.isNull(model)) { | if (Objects.isNull(model)) { | ||||
log.error("此 【{}】区域找不到 预审流程配置", regionCode); | log.error("此 【{}】区域找不到 预审流程配置", regionCode); | ||||
@@ -196,6 +199,10 @@ public class PrequalificationDeclaredProjectManage { | |||||
//保存预审项目 | //保存预审项目 | ||||
preModifyProject(projectInfo, instanceId); | preModifyProject(projectInfo, instanceId); | ||||
//发送给第一个审批人消息 | |||||
noticeManage.sendFirtUser(projectInfo,model.getFormName(),instanceId, | |||||
WorkNoticeContant.PASS_MSG_TEMPLATE, MsgTypeEnum.PROJECT_REVIEW); | |||||
return instanceId; | return instanceId; | ||||
} | } | ||||
@@ -243,6 +250,7 @@ public class PrequalificationDeclaredProjectManage { | |||||
ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS_SUCCESS.getCode())); | ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS_SUCCESS.getCode())); | ||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | ||||
buildPermission(query,user); | buildPermission(query,user); | ||||
query.eq(Project::getNewest,Boolean.TRUE); | |||||
Page<Project> page = projectService.page(req.page(), query); | Page<Project> page = projectService.page(req.page(), query); | ||||
long total; | long total; | ||||
if ((total = page.getTotal()) == 0) { | if ((total = page.getTotal()) == 0) { | ||||
@@ -304,6 +312,7 @@ public class PrequalificationDeclaredProjectManage { | |||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | ||||
//角色权限 | //角色权限 | ||||
buildPermission(query,user); | buildPermission(query,user); | ||||
query.eq(Project::getNewest,Boolean.TRUE); | |||||
List<Project> records = projectService.list(query); | List<Project> records = projectService.list(query); | ||||
List<PretrialDeclaredExportDTO> collect = records.stream().map(r -> { | List<PretrialDeclaredExportDTO> collect = records.stream().map(r -> { | ||||
@@ -87,7 +87,8 @@ public class ProjectAdjustmentManage { | |||||
VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("调整失败 此项目不存在!"); | VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("调整失败 此项目不存在!"); | ||||
//项目名称去重 | //项目名称去重 | ||||
if(StringUtils.isNotBlank(projectDto.getProjectName())){ | |||||
if(StringUtils.isNotBlank(projectDto.getProjectName()) && | |||||
!projectDto.getProjectName().equals(projectInfo.getProjectName())){ | |||||
defaultDeclaredProjectManage.checkDuplication(projectDto); | defaultDeclaredProjectManage.checkDuplication(projectDto); | ||||
} | } | ||||
@@ -97,9 +98,9 @@ public class ProjectAdjustmentManage { | |||||
} | } | ||||
//修改项目内容 | //修改项目内容 | ||||
if(!modifyProject(projectDto)){ | |||||
throw new BusinessException("调整项目失败!"); | |||||
} | |||||
// if(!modifyProject(projectDto)){ | |||||
// throw new BusinessException("调整项目失败!"); | |||||
// } | |||||
//最后去重新 提交项目流程 不同的状态 提交到不同的工作流去 | //最后去重新 提交项目流程 不同的状态 提交到不同的工作流去 | ||||
Function<DefaultDeclaredDTO, String> declaredFunction = | Function<DefaultDeclaredDTO, String> declaredFunction = | ||||
@@ -1,17 +1,17 @@ | |||||
package com.ningdatech.pmapi.projectdeclared.manage; | package com.ningdatech.pmapi.projectdeclared.manage; | ||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.TypeReference; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.google.common.collect.Maps; | import com.google.common.collect.Maps; | ||||
import com.ningdatech.basic.function.VUtils; | import com.ningdatech.basic.function.VUtils; | ||||
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | ||||
import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectConditionDTO; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||||
import com.ningdatech.pmapi.sys.manage.NoticeManage; | |||||
import com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant; | |||||
import com.wflow.bean.entity.WflowModels; | import com.wflow.bean.entity.WflowModels; | ||||
import com.wflow.exception.BusinessException; | import com.wflow.exception.BusinessException; | ||||
import com.wflow.workflow.bean.dto.OrgInfoDTO; | import com.wflow.workflow.bean.dto.OrgInfoDTO; | ||||
@@ -20,10 +20,8 @@ import com.wflow.workflow.service.ProcessInstanceService; | |||||
import com.wflow.workflow.service.ProcessModelService; | import com.wflow.workflow.service.ProcessModelService; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.springframework.beans.BeanUtils; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Map; | import java.util.Map; | ||||
@@ -50,6 +48,8 @@ public class ReviewByDeptJointManage { | |||||
private final DefaultDeclaredProjectManage declaredProjectManage; | private final DefaultDeclaredProjectManage declaredProjectManage; | ||||
private final DefaultDeclaredProjectManage defaultDeclaredProjectManage; | private final DefaultDeclaredProjectManage defaultDeclaredProjectManage; | ||||
private final NoticeManage noticeManage; | |||||
/** | /** | ||||
* 部门联审 | * 部门联审 | ||||
* @param project | * @param project | ||||
@@ -103,6 +103,10 @@ public class ReviewByDeptJointManage { | |||||
return Boolean.FALSE; | return Boolean.FALSE; | ||||
} | } | ||||
//发送给第一个审批人消息 | |||||
noticeManage.sendFirtUser(projectInfo,model.getFormName(),instanceId, | |||||
WorkNoticeContant.PASS_MSG_TEMPLATE, MsgTypeEnum.PROJECT_REVIEW); | |||||
return Boolean.TRUE; | return Boolean.TRUE; | ||||
} | } | ||||
@@ -6,17 +6,22 @@ import com.ningdatech.file.service.FileService; | |||||
import com.ningdatech.pmapi.projectdeclared.converter.ApplicationConverter; | import com.ningdatech.pmapi.projectdeclared.converter.ApplicationConverter; | ||||
import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | |||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.provincial.service.IJoinReviewProvincialBureauService; | import com.ningdatech.pmapi.provincial.service.IJoinReviewProvincialBureauService; | ||||
import com.ningdatech.pmapi.staging.service.IProjectStagingService; | |||||
import com.ningdatech.pmapi.todocenter.constant.TodoCenterContant; | |||||
import com.wflow.exception.BusinessException; | import com.wflow.exception.BusinessException; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
import java.time.LocalDateTime; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Objects; | import java.util.Objects; | ||||
@@ -39,6 +44,10 @@ public class ReviewByProvincialDeptManage { | |||||
private final IProjectApplicationService applicationService; | private final IProjectApplicationService applicationService; | ||||
private final ProjectLibManage projectLibManage; | |||||
private final IProjectStagingService projectStagingService; | |||||
/** | /** | ||||
* 省级部门联审 | * 省级部门联审 | ||||
* @param project | * @param project | ||||
@@ -88,12 +97,23 @@ public class ReviewByProvincialDeptManage { | |||||
// 对接省级联审的接口 | // 对接省级联审的接口 | ||||
List<ProjectApplication> applications = applicationService.list(Wrappers.lambdaQuery(ProjectApplication.class) | List<ProjectApplication> applications = applicationService.list(Wrappers.lambdaQuery(ProjectApplication.class) | ||||
.eq(ProjectApplication::getProjectId, projectInfo.getId())); | .eq(ProjectApplication::getProjectId, projectInfo.getId())); | ||||
Project p = projectLibManage.saveProjectWithVersionAndStatus(project,null, | |||||
ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS.getCode()); | |||||
//入库暂存表 后续处理 对接外部接口 | |||||
p.setUpdateOn(LocalDateTime.now()); | |||||
//保存一下 当前的主管单位发起人 | |||||
p.setPreStartUserId(p.getSponsor()); | |||||
//当前实例置为空 | |||||
p.setInstCode(TodoCenterContant.Declared.NULL_INST_CODE); | |||||
declaringDTO.getProjectInfo().setId(p.getId()); | |||||
projectService.updateById(p); | |||||
if(!joinReviewProvincialBureauService.pushImportProject( | if(!joinReviewProvincialBureauService.pushImportProject( | ||||
ApplicationConverter.convertProject(projectInfo,applications,fileService))){ | |||||
ApplicationConverter.convertProject(p,applications,fileService))){ | |||||
throw new BusinessException("提交省级部门联审失败"); | throw new BusinessException("提交省级部门联审失败"); | ||||
} | } | ||||
projectInfo.setStatus(ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS.getCode()); | |||||
projectService.updateById(projectInfo); | |||||
return String.valueOf(projectInfo.getId()); | |||||
return String.valueOf(p.getId()); | |||||
} | } | ||||
} | } |
@@ -299,6 +299,9 @@ public class ProjectDraft implements Serializable { | |||||
@ApiModelProperty("用户id") | @ApiModelProperty("用户id") | ||||
private String userId; | private String userId; | ||||
@ApiModelProperty("项目申报书") | |||||
private String projectApplicationForm; | |||||
private Long createBy; | private Long createBy; | ||||
private Long updateBy; | private Long updateBy; | ||||
} | } |
@@ -303,6 +303,8 @@ public class ProjectDraftVO implements Serializable { | |||||
@ApiModelProperty("21位项目编号") | @ApiModelProperty("21位项目编号") | ||||
private String projectCode; | private String projectCode; | ||||
@ApiModelProperty("项目申报书") | |||||
private String projectApplicationForm; | |||||
private Long createBy; | private Long createBy; | ||||
private Long updateBy; | private Long updateBy; | ||||
@@ -31,15 +31,15 @@ public class GenerateProjectCodeUtil { | |||||
@Autowired | @Autowired | ||||
private IProjectService projectService; | private IProjectService projectService; | ||||
public String generateProjectCode(ProjectDTO projectInfo){ | |||||
public String generateProjectCode(ProjectDTO project){ | |||||
// 获取所属行政区划代码(6位) | // 获取所属行政区划代码(6位) | ||||
String areaCode = projectInfo.getAreaCode(); | |||||
String areaCode = project.getAreaCode(); | |||||
// 获取建设年度后两位 | // 获取建设年度后两位 | ||||
String year = String.valueOf(projectInfo.getProjectYear() % DeclaredProjectContant.Project.YEAR_DRAW_SURPLUS); | |||||
String year = String.valueOf(project.getProjectYear() % DeclaredProjectContant.Project.YEAR_DRAW_SURPLUS); | |||||
// 9-12位固定 | // 9-12位固定 | ||||
String fixedNumber = DeclaredProjectContant.Project.FIXED_NUMBER; | String fixedNumber = DeclaredProjectContant.Project.FIXED_NUMBER; | ||||
// 获取公司的财政编码 | // 获取公司的财政编码 | ||||
CompanyFiscalCode companyFiscalCode = companyFiscalCodeService.getByOrganizationCode(projectInfo.getBuildOrgCode()); | |||||
CompanyFiscalCode companyFiscalCode = companyFiscalCodeService.getByOrganizationCode(project.getBuildOrgCode()); | |||||
// 从表中查出单位配置的财政编码 | // 从表中查出单位配置的财政编码 | ||||
if (Objects.isNull(companyFiscalCode)){ | if (Objects.isNull(companyFiscalCode)){ | ||||
@@ -51,8 +51,8 @@ public class GenerateProjectCodeUtil { | |||||
String projectIdStr; | String projectIdStr; | ||||
// 获取项目库当前最大项目序号 | // 获取项目库当前最大项目序号 | ||||
List<Project> projectList = projectService.list(Wrappers.lambdaQuery(Project.class).orderByDesc(Project::getId)); | List<Project> projectList = projectService.list(Wrappers.lambdaQuery(Project.class).orderByDesc(Project::getId)); | ||||
Project project = CollUtil.isEmpty(projectList) ? null : projectList.get(0); | |||||
Long projectId = Objects.isNull(project) ? DeclaredProjectContant.Project.MIN_PROJECT_ID : project.getId() + 1; | |||||
Project maxProject = CollUtil.isEmpty(projectList) ? null : projectList.get(0); | |||||
Long projectId = Objects.isNull(maxProject) ? DeclaredProjectContant.Project.MIN_PROJECT_ID : maxProject.getId() + 1; | |||||
if (projectId > DeclaredProjectContant.Project.MAX_PROJECT_ID){ | if (projectId > DeclaredProjectContant.Project.MAX_PROJECT_ID){ | ||||
// 超过999的项目号从1开始 1 | // 超过999的项目号从1开始 1 | ||||
Long newProjectId = projectId % DeclaredProjectContant.Project.MAX_PROJECT_ID; | Long newProjectId = projectId % DeclaredProjectContant.Project.MAX_PROJECT_ID; | ||||
@@ -1,6 +1,6 @@ | |||||
package com.ningdatech.pmapi.projectlib.constant; | package com.ningdatech.pmapi.projectlib.constant; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ImportTemplateEnum; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectLibFlagEnum; | |||||
import java.util.*; | import java.util.*; | ||||
@@ -15,16 +15,16 @@ import java.util.*; | |||||
*/ | */ | ||||
public class ImportTemplateConstant { | public class ImportTemplateConstant { | ||||
public static final List<String> ANNUAL_PLAN_COL_LIST = Arrays.asList("序号","项目id","项目名称","建设内容","建设依据","建设性质","建设起止年限(填写到月)", "总投资", "自有资金", "政府投资-本级财政","政府投资-上级补助资金","银行贷款","其他","一季度","二季度","三季度","四季度","建设单位","项目联系人","项目分管领导","备注"); | |||||
public static final List<String> ANNUAL_PLAN_COL_LIST = Arrays.asList("序号","项目id","项目名称","建设内容","建设依据","建设性质","建设起止年限(填写到月)", "总投资", "自有资金","年度投资额","政府投资-本级财政","政府投资-上级补助资金","银行贷款","其他","一季度","二季度","三季度","四季度","建设单位","项目联系人","项目分管领导","备注"); | |||||
private static final Map<ImportTemplateEnum, List<String>> IMPORT_TEMPLATE_MAP; | |||||
private static final Map<ProjectLibFlagEnum, List<String>> IMPORT_TEMPLATE_MAP; | |||||
static { | static { | ||||
IMPORT_TEMPLATE_MAP = new HashMap<>(ImportTemplateEnum.values().length); | |||||
IMPORT_TEMPLATE_MAP.put(ImportTemplateEnum.ANNUAL_PLAN, ANNUAL_PLAN_COL_LIST); | |||||
IMPORT_TEMPLATE_MAP = new HashMap<>(ProjectLibFlagEnum.values().length); | |||||
IMPORT_TEMPLATE_MAP.put(ProjectLibFlagEnum.ANNUAL_PLAN, ANNUAL_PLAN_COL_LIST); | |||||
} | } | ||||
public static List<String> getTemplateTitle(ImportTemplateEnum template) { | |||||
public static List<String> getTemplateTitle(ProjectLibFlagEnum template) { | |||||
return IMPORT_TEMPLATE_MAP.getOrDefault(template, Collections.emptyList()); | return IMPORT_TEMPLATE_MAP.getOrDefault(template, Collections.emptyList()); | ||||
} | } | ||||
@@ -2,7 +2,7 @@ package com.ningdatech.pmapi.projectlib.controller; | |||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
import com.ningdatech.log.annotation.WebLog; | import com.ningdatech.log.annotation.WebLog; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ImportTemplateEnum; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectLibFlagEnum; | |||||
import com.ningdatech.pmapi.projectlib.manage.AnnualPlanLibManage; | import com.ningdatech.pmapi.projectlib.manage.AnnualPlanLibManage; | ||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | ||||
import com.ningdatech.pmapi.projectlib.model.req.ProjectApprovedReq; | import com.ningdatech.pmapi.projectlib.model.req.ProjectApprovedReq; | ||||
@@ -65,8 +65,8 @@ public class AnnualPlanController { | |||||
@PostMapping("/importAnnualPlan") | @PostMapping("/importAnnualPlan") | ||||
@ApiOperation("导入年度计划") | @ApiOperation("导入年度计划") | ||||
@WebLog("导入年度计划") | @WebLog("导入年度计划") | ||||
public void importAnnualPlan(@RequestParam("template") ImportTemplateEnum template, MultipartFile file) { | |||||
annualPlanLibManage.importAnnualPlan(template,file); | |||||
public void importAnnualPlan(@RequestParam("importFlag") ProjectLibFlagEnum importFlag, MultipartFile file) { | |||||
annualPlanLibManage.importAnnualPlan(importFlag,file); | |||||
} | } | ||||
@PostMapping("/modify") | @PostMapping("/modify") | ||||
@@ -77,9 +77,15 @@ public class AnnualPlanController { | |||||
} | } | ||||
@PostMapping("/exportList") | @PostMapping("/exportList") | ||||
@ApiOperation("项目库【列表|编辑表】导出") | |||||
@ApiOperation("项目(增补)库列表导出") | |||||
public void exportList(@Valid @RequestBody ProjectListReq param, HttpServletResponse response) { | public void exportList(@Valid @RequestBody ProjectListReq param, HttpServletResponse response) { | ||||
annualPlanLibManage.exportList(param, response); | annualPlanLibManage.exportList(param, response); | ||||
} | } | ||||
@PostMapping("/exportModifyList") | |||||
@ApiOperation("项目(增补)库编辑表导出") | |||||
public void exportModifyList(@Valid @RequestBody ProjectListReq param, HttpServletResponse response) { | |||||
annualPlanLibManage.exportModifyList(param, response); | |||||
} | |||||
} | } |
@@ -4,24 +4,25 @@ import lombok.Getter; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
* 导入模版枚举 | |||||
* 项目库标志枚举 | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author WendyYang | * @author WendyYang | ||||
* @since 2022-11-04 | * @since 2022-11-04 | ||||
*/ | */ | ||||
@Getter | @Getter | ||||
public enum ImportTemplateEnum { | |||||
public enum ProjectLibFlagEnum { | |||||
/** | /** | ||||
* 通用导入模版枚举 | |||||
* 项目库标志枚举 | |||||
*/ | */ | ||||
ANNUAL_PLAN("年度计划(增补)库导入"); | |||||
ANNUAL_PLAN("年度计划库"), | |||||
ANNUAL_PLAN_SUPPLEMENT("年度计划增补库"); | |||||
private final String value; | private final String value; | ||||
ImportTemplateEnum(String value) { | |||||
ProjectLibFlagEnum(String value) { | |||||
this.value = value; | this.value = value; | ||||
} | } | ||||
@@ -6,7 +6,11 @@ import java.util.Objects; | |||||
import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||
import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||
import com.ningdatech.basic.exception.BizException; | |||||
import com.ningdatech.basic.util.NdDateUtils; | import com.ningdatech.basic.util.NdDateUtils; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import com.ningdatech.pmapi.projectlib.utils.ProjectVersionUtil; | |||||
import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | ||||
import com.wflow.workflow.bean.process.ProgressNode; | import com.wflow.workflow.bean.process.ProgressNode; | ||||
import com.wflow.workflow.bean.vo.ProcessDetailVO; | import com.wflow.workflow.bean.vo.ProcessDetailVO; | ||||
@@ -36,32 +40,44 @@ public class ConstructionPlanReviewHandle extends AbstractProcessBusinessHandle | |||||
private final IProjectInstService projectInstService; | private final IProjectInstService projectInstService; | ||||
private final ProcessInstanceService processInstanceService; | private final ProcessInstanceService processInstanceService; | ||||
private final BuildUserUtils buildUserUtils; | private final BuildUserUtils buildUserUtils; | ||||
private final ProjectVersionUtil projectVersionUtil; | |||||
private final IProjectService projectService; | |||||
public ConstructionPlanReviewHandle(IProjectInstService projectInstService, ProcessInstanceService processInstanceService, BuildUserUtils buildUserUtils){ | |||||
public ConstructionPlanReviewHandle(IProjectInstService projectInstService, ProcessInstanceService processInstanceService, BuildUserUtils buildUserUtils, ProjectVersionUtil projectVersionUtil, IProjectService projectService){ | |||||
this.projectInstService = projectInstService; | this.projectInstService = projectInstService; | ||||
this.processInstanceService = processInstanceService; | this.processInstanceService = processInstanceService; | ||||
this.buildUserUtils = buildUserUtils; | this.buildUserUtils = buildUserUtils; | ||||
this.projectVersionUtil = projectVersionUtil; | |||||
this.projectService = projectService; | |||||
} | } | ||||
@Override | @Override | ||||
void businessHandle(Long projectId, List<ProcessDetailVO> processSchedule) { | void businessHandle(Long projectId, List<ProcessDetailVO> processSchedule) { | ||||
ProcessDetailVO processDetailVO = new ProcessDetailVO(); | ProcessDetailVO processDetailVO = new ProcessDetailVO(); | ||||
Project project = projectService.getById(projectId); | |||||
// 根据项目ID查询出建设方案评审流程的流程状态 | // 根据项目ID查询出建设方案评审流程的流程状态 | ||||
ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class) | ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class) | ||||
.eq(ProjectInst::getProjectId, projectId) | .eq(ProjectInst::getProjectId, projectId) | ||||
.eq(ProjectInst::getInstType, InstTypeEnum.CONSTRUCTION_PLAN_REVIEW.getCode()) | .eq(ProjectInst::getInstType, InstTypeEnum.CONSTRUCTION_PLAN_REVIEW.getCode()) | ||||
.orderByDesc(ProjectInst::getCreatOn) | .orderByDesc(ProjectInst::getCreatOn) | ||||
.last("limit 1")); | .last("limit 1")); | ||||
if (Objects.isNull(projectInst)){ | |||||
ProcessProgressVo instanceDetail = null; | |||||
// 未找到当前版本项目的建设方案审核流程且当前项目版本号大于1(是被驳回重新申报的项目) | |||||
if (Objects.isNull(projectInst)) { | |||||
if (project.getVersion() > CommonConst.VERSION_ONE ){ | |||||
// 获取上个版本的信息 | |||||
instanceDetail = projectVersionUtil.getPreVerProcessInfo(projectId,InstTypeEnum.CONSTRUCTION_PLAN_REVIEW); | |||||
} | |||||
}else { | |||||
String instCode = projectInst.getInstCode(); | |||||
instanceDetail = processInstanceService.getProgressInstanceDetail(null, instCode); | |||||
} | |||||
if (Objects.isNull(instanceDetail)){ | |||||
processDetailVO.setStepStatus(StepStatusEnum.NOT_START); | processDetailVO.setStepStatus(StepStatusEnum.NOT_START); | ||||
processDetailVO.setProcessName(CommonConst.CONSTRUCTION_PLAN_REVIEW); | processDetailVO.setProcessName(CommonConst.CONSTRUCTION_PLAN_REVIEW); | ||||
processSchedule.add(processDetailVO); | processSchedule.add(processDetailVO); | ||||
return; | return; | ||||
} | } | ||||
String instCode = projectInst.getInstCode(); | |||||
ProcessProgressVo instanceDetail = processInstanceService.getProgressInstanceDetail(null, instCode); | |||||
String status = instanceDetail.getStatus(); | String status = instanceDetail.getStatus(); | ||||
if (ProcessStatusEnum.UNDER_REVIEW.getDesc().equals(status)){ | if (ProcessStatusEnum.UNDER_REVIEW.getDesc().equals(status)){ | ||||
processDetailVO.setStepStatus(StepStatusEnum.ON_GOING); | processDetailVO.setStepStatus(StepStatusEnum.ON_GOING); | ||||
@@ -7,6 +7,7 @@ import java.util.Objects; | |||||
import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||
import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||
import com.ningdatech.basic.util.NdDateUtils; | import com.ningdatech.basic.util.NdDateUtils; | ||||
import com.ningdatech.pmapi.projectlib.utils.ProjectVersionUtil; | |||||
import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | ||||
import com.wflow.workflow.bean.process.ProgressNode; | import com.wflow.workflow.bean.process.ProgressNode; | ||||
import com.wflow.workflow.bean.vo.ProcessDetailVO; | import com.wflow.workflow.bean.vo.ProcessDetailVO; | ||||
@@ -24,7 +25,7 @@ import com.wflow.workflow.enums.ProcessStatusEnum; | |||||
import com.wflow.workflow.service.ProcessInstanceService; | import com.wflow.workflow.service.ProcessInstanceService; | ||||
/** | /** | ||||
* 单位内部审核处理 | |||||
* 部门联审审核处理 | |||||
* | * | ||||
* @author CMM | * @author CMM | ||||
* @since 2023/02/24 14:35 | * @since 2023/02/24 14:35 | ||||
@@ -36,11 +37,13 @@ public class DeptUnitedReviewHandle extends AbstractProcessBusinessHandle { | |||||
private final IProjectInstService projectInstService; | private final IProjectInstService projectInstService; | ||||
private final ProcessInstanceService processInstanceService; | private final ProcessInstanceService processInstanceService; | ||||
private final BuildUserUtils buildUserUtils; | private final BuildUserUtils buildUserUtils; | ||||
private final ProjectVersionUtil projectVersionUtil; | |||||
public DeptUnitedReviewHandle(IProjectInstService projectInstService, ProcessInstanceService processInstanceService, BuildUserUtils buildUserUtils){ | |||||
public DeptUnitedReviewHandle(IProjectInstService projectInstService, ProcessInstanceService processInstanceService, BuildUserUtils buildUserUtils, ProjectVersionUtil projectVersionUtil){ | |||||
this.projectInstService = projectInstService; | this.projectInstService = projectInstService; | ||||
this.processInstanceService = processInstanceService; | this.processInstanceService = processInstanceService; | ||||
this.buildUserUtils = buildUserUtils; | this.buildUserUtils = buildUserUtils; | ||||
this.projectVersionUtil = projectVersionUtil; | |||||
} | } | ||||
@Override | @Override | ||||
@@ -3,11 +3,15 @@ package com.ningdatech.pmapi.projectlib.handle; | |||||
import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||
import com.ningdatech.basic.exception.BizException; | |||||
import com.ningdatech.basic.util.NdDateUtils; | import com.ningdatech.basic.util.NdDateUtils; | ||||
import com.ningdatech.pmapi.common.constant.CommonConst; | import com.ningdatech.pmapi.common.constant.CommonConst; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; | import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import com.ningdatech.pmapi.projectlib.utils.ProjectVersionUtil; | |||||
import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | ||||
import com.wflow.workflow.bean.process.ProgressNode; | import com.wflow.workflow.bean.process.ProgressNode; | ||||
import com.wflow.workflow.bean.vo.ProcessDetailVO; | import com.wflow.workflow.bean.vo.ProcessDetailVO; | ||||
@@ -35,30 +39,47 @@ public class PreliminaryPreviewHandle extends AbstractProcessBusinessHandle { | |||||
private final IProjectInstService projectInstService; | private final IProjectInstService projectInstService; | ||||
private final ProcessInstanceService processInstanceService; | private final ProcessInstanceService processInstanceService; | ||||
private final BuildUserUtils buildUserUtils; | private final BuildUserUtils buildUserUtils; | ||||
private final ProjectVersionUtil projectVersionUtil; | |||||
private final IProjectService projectService; | |||||
public PreliminaryPreviewHandle(IProjectInstService projectInstService, ProcessInstanceService processInstanceService, BuildUserUtils buildUserUtils) { | |||||
public PreliminaryPreviewHandle(IProjectInstService projectInstService, ProcessInstanceService processInstanceService, BuildUserUtils buildUserUtils, ProjectVersionUtil projectVersionUtil, IProjectService projectService) { | |||||
this.projectInstService = projectInstService; | this.projectInstService = projectInstService; | ||||
this.processInstanceService = processInstanceService; | this.processInstanceService = processInstanceService; | ||||
this.buildUserUtils = buildUserUtils; | this.buildUserUtils = buildUserUtils; | ||||
this.projectVersionUtil = projectVersionUtil; | |||||
this.projectService = projectService; | |||||
} | } | ||||
@Override | @Override | ||||
void businessHandle(Long projectId, List<ProcessDetailVO> processSchedule) { | void businessHandle(Long projectId, List<ProcessDetailVO> processSchedule) { | ||||
ProcessDetailVO processDetailVO = new ProcessDetailVO(); | ProcessDetailVO processDetailVO = new ProcessDetailVO(); | ||||
Project project = projectService.getById(projectId); | |||||
if (Objects.isNull(project)){ | |||||
throw new BizException("当前项目不存在!"); | |||||
} | |||||
// 根据项目ID查询项目预审流程的流程状态 | // 根据项目ID查询项目预审流程的流程状态 | ||||
ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class) | ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class) | ||||
.eq(ProjectInst::getProjectId, projectId) | .eq(ProjectInst::getProjectId, projectId) | ||||
.eq(ProjectInst::getInstType, InstTypeEnum.PRELIMINARY_PREVIEW.getCode()) | .eq(ProjectInst::getInstType, InstTypeEnum.PRELIMINARY_PREVIEW.getCode()) | ||||
.orderByDesc(ProjectInst::getCreatOn) | .orderByDesc(ProjectInst::getCreatOn) | ||||
.last("limit 1")); | .last("limit 1")); | ||||
if (Objects.isNull(projectInst)){ | |||||
ProcessProgressVo instanceDetail = null; | |||||
// 未找到当前版本项目的预审审核流程且当前项目版本号大于1(是被驳回重新申报的项目) | |||||
if (Objects.isNull(projectInst)) { | |||||
if (project.getVersion() > CommonConst.VERSION_ONE){ | |||||
// 获取上个版本的信息 | |||||
instanceDetail = projectVersionUtil.getPreVerProcessInfo(projectId,InstTypeEnum.PRELIMINARY_PREVIEW); | |||||
} | |||||
}else { | |||||
String instCode = projectInst.getInstCode(); | |||||
instanceDetail = processInstanceService.getProgressInstanceDetail(null, instCode); | |||||
} | |||||
if (Objects.isNull(instanceDetail)){ | |||||
processDetailVO.setStepStatus(StepStatusEnum.NOT_START); | processDetailVO.setStepStatus(StepStatusEnum.NOT_START); | ||||
processDetailVO.setProcessName(CommonConst.PRELIMINARY_PREVIEW); | processDetailVO.setProcessName(CommonConst.PRELIMINARY_PREVIEW); | ||||
processSchedule.add(processDetailVO); | processSchedule.add(processDetailVO); | ||||
return; | return; | ||||
} | } | ||||
String instCode = projectInst.getInstCode(); | |||||
ProcessProgressVo instanceDetail = processInstanceService.getProgressInstanceDetail(null, instCode); | |||||
String status = instanceDetail.getStatus(); | String status = instanceDetail.getStatus(); | ||||
if (ProcessStatusEnum.UNDER_REVIEW.getDesc().equals(status)){ | if (ProcessStatusEnum.UNDER_REVIEW.getDesc().equals(status)){ | ||||
processDetailVO.setStepStatus(StepStatusEnum.ON_GOING); | processDetailVO.setStepStatus(StepStatusEnum.ON_GOING); | ||||
@@ -1,19 +1,24 @@ | |||||
package com.ningdatech.pmapi.projectlib.handle; | package com.ningdatech.pmapi.projectlib.handle; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.Date; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Objects; | |||||
import java.util.stream.Collectors; | |||||
import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||
import com.ningdatech.basic.exception.BizException; | |||||
import com.ningdatech.basic.util.NdDateUtils; | import com.ningdatech.basic.util.NdDateUtils; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; | import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | ||||
import com.ningdatech.pmapi.common.constant.CommonConst; | import com.ningdatech.pmapi.common.constant.CommonConst; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import com.ningdatech.pmapi.projectlib.utils.ProjectVersionUtil; | |||||
import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | ||||
import com.wflow.workflow.bean.dto.ProcessInstanceUserDto; | import com.wflow.workflow.bean.dto.ProcessInstanceUserDto; | ||||
import com.wflow.workflow.bean.process.ProgressNode; | import com.wflow.workflow.bean.process.ProgressNode; | ||||
@@ -39,25 +44,43 @@ public class UnitInnerAuditHandle extends AbstractProcessBusinessHandle { | |||||
private final ProcessInstanceService processInstanceService; | private final ProcessInstanceService processInstanceService; | ||||
private final BuildUserUtils buildUserUtils; | private final BuildUserUtils buildUserUtils; | ||||
private final ProjectVersionUtil projectVersionUtil; | |||||
private final IProjectService projectService; | |||||
public UnitInnerAuditHandle(IProjectInstService projectInstService, ProcessInstanceService processInstanceService, BuildUserUtils buildUserUtils){ | |||||
public UnitInnerAuditHandle(IProjectInstService projectInstService, ProcessInstanceService processInstanceService, BuildUserUtils buildUserUtils, ProjectVersionUtil projectVersionUtil, IProjectService projectService){ | |||||
this.projectInstService = projectInstService; | this.projectInstService = projectInstService; | ||||
this.processInstanceService = processInstanceService; | this.processInstanceService = processInstanceService; | ||||
this.buildUserUtils = buildUserUtils; | this.buildUserUtils = buildUserUtils; | ||||
this.projectVersionUtil = projectVersionUtil; | |||||
this.projectService = projectService; | |||||
} | } | ||||
@Override | @Override | ||||
void businessHandle(Long projectId, List<ProcessDetailVO> processSchedule) { | void businessHandle(Long projectId, List<ProcessDetailVO> processSchedule) { | ||||
ProcessDetailVO processDetailVO = new ProcessDetailVO(); | ProcessDetailVO processDetailVO = new ProcessDetailVO(); | ||||
Project project = projectService.getById(projectId); | |||||
// 根据项目ID查询出单位内部审核流程的流程状态 | // 根据项目ID查询出单位内部审核流程的流程状态 | ||||
// 注意:已经在项目库中的项目,一定是单位内部审核已经开始的项目 | |||||
ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class) | ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class) | ||||
.eq(ProjectInst::getProjectId, projectId) | .eq(ProjectInst::getProjectId, projectId) | ||||
.eq(ProjectInst::getInstType, InstTypeEnum.UNIT_INNER_AUDIT.getCode()) | .eq(ProjectInst::getInstType, InstTypeEnum.UNIT_INNER_AUDIT.getCode()) | ||||
.orderByDesc(ProjectInst::getCreatOn) | .orderByDesc(ProjectInst::getCreatOn) | ||||
.last("limit 1")); | .last("limit 1")); | ||||
String instCode = projectInst.getInstCode(); | |||||
ProcessProgressVo instanceDetail = processInstanceService.getProgressInstanceDetail(null, instCode); | |||||
ProcessProgressVo instanceDetail = null; | |||||
// 未找到当前版本项目的单位内部审核流程且当前项目版本号大于1(是被驳回重新申报的项目) | |||||
// 注意:已经在项目库中的项目,一定是单位内部审核已经开始的项目 | |||||
if (Objects.isNull(projectInst)) { | |||||
if (project.getVersion() > CommonConst.VERSION_ONE){ | |||||
// 获取上个版本的信息 | |||||
instanceDetail = projectVersionUtil.getPreVerProcessInfo(projectId, InstTypeEnum.UNIT_INNER_AUDIT); | |||||
} | |||||
}else { | |||||
String instCode = projectInst.getInstCode(); | |||||
instanceDetail = processInstanceService.getProgressInstanceDetail(null, instCode); | |||||
} | |||||
if (Objects.isNull(instanceDetail)){ | |||||
throw new BizException("未获取到单位内部审核流程详情!"); | |||||
} | |||||
String status = instanceDetail.getStatus(); | String status = instanceDetail.getStatus(); | ||||
if (ProcessStatusEnum.UNDER_REVIEW.getDesc().equals(status)){ | if (ProcessStatusEnum.UNDER_REVIEW.getDesc().equals(status)){ | ||||
processDetailVO.setStepStatus(StepStatusEnum.ON_GOING); | processDetailVO.setStepStatus(StepStatusEnum.ON_GOING); | ||||
@@ -75,6 +98,7 @@ public class UnitInnerAuditHandle extends AbstractProcessBusinessHandle { | |||||
if (StepStatusEnum.contains(processDetailVO.getStepStatus(), | if (StepStatusEnum.contains(processDetailVO.getStepStatus(), | ||||
Lists.newArrayList(StepStatusEnum.REJECTED, | Lists.newArrayList(StepStatusEnum.REJECTED, | ||||
StepStatusEnum.COMPLETED))) { | StepStatusEnum.COMPLETED))) { | ||||
// 如果是驳回,获取流程信息时可能 | |||||
ProgressNode progressNode = progressInfo.get(progressInfo.size() - 1); | ProgressNode progressNode = progressInfo.get(progressInfo.size() - 1); | ||||
LocalDateTime finishTime = NdDateUtils.date2LocalDateTime(progressNode.getFinishTime()); | LocalDateTime finishTime = NdDateUtils.date2LocalDateTime(progressNode.getFinishTime()); | ||||
processDetailVO.setFinishTime(finishTime); | processDetailVO.setFinishTime(finishTime); | ||||
@@ -1,12 +1,13 @@ | |||||
package com.ningdatech.pmapi.projectlib.manage; | package com.ningdatech.pmapi.projectlib.manage; | ||||
import cn.afterturn.easypoi.excel.ExcelExportUtil; | |||||
import cn.afterturn.easypoi.excel.ExcelImportUtil; | |||||
import cn.afterturn.easypoi.excel.entity.ImportParams; | |||||
import cn.afterturn.easypoi.excel.entity.TemplateExportParams; | |||||
import cn.hutool.core.bean.BeanUtil; | import cn.hutool.core.bean.BeanUtil; | ||||
import cn.hutool.core.lang.Assert; | |||||
import cn.hutool.poi.excel.ExcelReader; | |||||
import cn.hutool.poi.excel.ExcelUtil; | import cn.hutool.poi.excel.ExcelUtil; | ||||
import com.alibaba.excel.EasyExcel; | |||||
import com.alibaba.excel.context.AnalysisContext; | |||||
import com.alibaba.excel.event.AnalysisEventListener; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
@@ -14,7 +15,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.basic.model.PageVo; | 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.StrPool; | |||||
import com.ningdatech.pmapi.common.constant.CommonConst; | import com.ningdatech.pmapi.common.constant.CommonConst; | ||||
import com.ningdatech.pmapi.common.enumeration.CommonEnum; | import com.ningdatech.pmapi.common.enumeration.CommonEnum; | ||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | import com.ningdatech.pmapi.common.helper.UserInfoHelper; | ||||
@@ -23,35 +24,44 @@ import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | import com.ningdatech.pmapi.common.util.ExcelDownUtil; | ||||
import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | ||||
import com.ningdatech.pmapi.datascope.utils.DataScopeUtil; | import com.ningdatech.pmapi.datascope.utils.DataScopeUtil; | ||||
import com.ningdatech.pmapi.projectlib.constant.ImportTemplateConstant; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ImportTemplateEnum; | |||||
import com.ningdatech.pmapi.expert.constant.ExpertUserInfoSensitiveFieldEnum; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectLibFlagEnum; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectRenewalApprovalStatusEnum; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import com.ningdatech.pmapi.projectlib.helper.ProjectHelper; | import com.ningdatech.pmapi.projectlib.helper.ProjectHelper; | ||||
import com.ningdatech.pmapi.projectlib.model.dto.AnnualLibExportDTO; | |||||
import com.ningdatech.pmapi.projectlib.model.dto.AnnualLibImportDTO; | import com.ningdatech.pmapi.projectlib.model.dto.AnnualLibImportDTO; | ||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectRenewalFundDeclaration; | |||||
import com.ningdatech.pmapi.projectlib.model.req.ProjectApprovedReq; | import com.ningdatech.pmapi.projectlib.model.req.ProjectApprovedReq; | ||||
import com.ningdatech.pmapi.projectlib.model.req.ProjectIdReq; | import com.ningdatech.pmapi.projectlib.model.req.ProjectIdReq; | ||||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | ||||
import com.ningdatech.pmapi.projectlib.model.req.StartProjectDeclareReq; | import com.ningdatech.pmapi.projectlib.model.req.StartProjectDeclareReq; | ||||
import com.ningdatech.pmapi.projectlib.model.vo.AnnualPlanListItemVO; | import com.ningdatech.pmapi.projectlib.model.vo.AnnualPlanListItemVO; | ||||
import com.ningdatech.pmapi.projectlib.service.INdProjectStatusChangeService; | import com.ningdatech.pmapi.projectlib.service.INdProjectStatusChangeService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectRenewalFundDeclarationService; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.apache.commons.collections4.CollectionUtils; | import org.apache.commons.collections4.CollectionUtils; | ||||
import org.apache.poi.ss.usermodel.Workbook; | |||||
import org.springframework.beans.BeanUtils; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
import org.springframework.web.multipart.MultipartFile; | import org.springframework.web.multipart.MultipartFile; | ||||
import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.io.*; | |||||
import java.net.URLEncoder; | |||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.*; | import java.util.*; | ||||
import java.util.stream.Collectors; | |||||
import static com.ningdatech.pmapi.expert.constant.ExpertUserInfoSensitiveFieldEnum.UnitType.list; | |||||
import static com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum.*; | import static com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum.*; | ||||
/** | /** | ||||
@@ -71,27 +81,15 @@ public class AnnualPlanLibManage { | |||||
private final StateMachineUtils stateMachine; | private final StateMachineUtils stateMachine; | ||||
private final INdProjectStatusChangeService statusChangeService; | private final INdProjectStatusChangeService statusChangeService; | ||||
private final UserInfoHelper userInfoHelper; | private final UserInfoHelper userInfoHelper; | ||||
private final IProjectRenewalFundDeclarationService projectRenewalFundDeclarationService; | |||||
/** | /** | ||||
* 年度计划查询状态 | * 年度计划查询状态 | ||||
*/ | */ | ||||
private static final List<ProjectStatusEnum> ANNUAL_PLAN_LIST_STATUS = Arrays.asList( | |||||
IN_THE_ANNUAL_PLAN, | |||||
SCHEME_UNDER_REVIEW, | |||||
SCHEME_REVIEW_FAILED, | |||||
TO_BE_APPROVED, | |||||
TO_BE_DECLARED, | |||||
PLAN_TO_BE_DECLARED, | |||||
PENDING_PREQUALIFICATION_CHOICE, | |||||
PROJECT_APPROVED, | |||||
TO_BE_PURCHASED, | |||||
UNDER_CONSTRUCTION, | |||||
TO_BE_FINALLY_INSPECTED, | |||||
FINAL_ACCEPTANCE_IS_UNDER_REVIEW, | |||||
FINAL_ACCEPTANCE_REVIEW_FAILED, | |||||
ARCHIVED | |||||
); | |||||
private static final List<ProjectStatusEnum> ANNUAL_PLAN_LIST_STATUS = | |||||
Arrays.asList(IN_THE_ANNUAL_PLAN, SCHEME_UNDER_REVIEW, SCHEME_REVIEW_FAILED, TO_BE_APPROVED, TO_BE_DECLARED, | |||||
PLAN_TO_BE_DECLARED, PENDING_PREQUALIFICATION_CHOICE, PROJECT_APPROVED, TO_BE_PURCHASED, UNDER_CONSTRUCTION, | |||||
TO_BE_FINALLY_INSPECTED, FINAL_ACCEPTANCE_IS_UNDER_REVIEW, FINAL_ACCEPTANCE_REVIEW_FAILED, ARCHIVED); | |||||
public PageVo<AnnualPlanListItemVO> annulPlanLibList(ProjectListReq req) { | public PageVo<AnnualPlanListItemVO> annulPlanLibList(ProjectListReq req) { | ||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | ||||
@@ -100,9 +98,10 @@ public class AnnualPlanLibManage { | |||||
throw new BizException("请传入是否临时增补标志!"); | throw new BizException("请传入是否临时增补标志!"); | ||||
} | } | ||||
query.eq(Project::getIsTemporaryAugment, isTemporaryAugment); | query.eq(Project::getIsTemporaryAugment, isTemporaryAugment); | ||||
query.eq(Project::getNewest, Boolean.TRUE); | |||||
query.orderByDesc(Project::getAnnualPlanAddTime); | query.orderByDesc(Project::getAnnualPlanAddTime); | ||||
query.in(Project::getStatus, CollUtils.fieldList(ANNUAL_PLAN_LIST_STATUS, ProjectStatusEnum::getCode)); | query.in(Project::getStatus, CollUtils.fieldList(ANNUAL_PLAN_LIST_STATUS, ProjectStatusEnum::getCode)); | ||||
//数据权限 | |||||
// 数据权限 | |||||
buildProjectLibPermission(query); | buildProjectLibPermission(query); | ||||
Page<Project> page = projectService.page(req.page(), query); | Page<Project> page = projectService.page(req.page(), query); | ||||
long total; | long total; | ||||
@@ -122,6 +121,7 @@ public class AnnualPlanLibManage { | |||||
item.setDeclaredAmount(w.getDeclareAmount()); | item.setDeclaredAmount(w.getDeclareAmount()); | ||||
item.setBuildOrg(w.getBuildOrgName()); | item.setBuildOrg(w.getBuildOrgName()); | ||||
item.setCreateOn(w.getCreateOn()); | item.setCreateOn(w.getCreateOn()); | ||||
item.setApprovalAmount(w.getApprovalAmount()); | |||||
item.setIsStartDeclaredProject(!IN_THE_ANNUAL_PLAN.eq(w.getStatus())); | item.setIsStartDeclaredProject(!IN_THE_ANNUAL_PLAN.eq(w.getStatus())); | ||||
result.getRecords().add(item); | result.getRecords().add(item); | ||||
}); | }); | ||||
@@ -150,15 +150,12 @@ public class AnnualPlanLibManage { | |||||
public void projectApproved(ProjectApprovedReq req) { | public void projectApproved(ProjectApprovedReq req) { | ||||
Project project = projectService.getById(req.getProjectId()); | Project project = projectService.getById(req.getProjectId()); | ||||
stateMachine.pass(project); | stateMachine.pass(project); | ||||
LambdaUpdateWrapper<Project> update = Wrappers.lambdaUpdate(Project.class) | |||||
.set(Project::getApprovalAmount, req.getApprovedAmount()) | |||||
.set(Project::getApprovedFile, req.getApprovedFileId()) | |||||
.set(Project::getBuildCycle, req.getBuildCycle()) | |||||
LambdaUpdateWrapper<Project> update = | |||||
Wrappers.lambdaUpdate(Project.class).set(Project::getApprovalAmount, req.getApprovedAmount()) | |||||
.set(Project::getApprovedFile, req.getApprovedFileId()).set(Project::getBuildCycle, req.getBuildCycle()) | |||||
.set(Project::getApprovedConstructionPlanFile, req.getBuildPlanFileId()) | .set(Project::getApprovedConstructionPlanFile, req.getBuildPlanFileId()) | ||||
.set(Project::getApprovalDate, req.getApprovedDate()) | |||||
.set(Project::getStatus, project.getStatus()) | |||||
.set(Project::getStage, project.getStage()) | |||||
.eq(Project::getId, req.getProjectId()); | |||||
.set(Project::getApprovalDate, req.getApprovedDate()).set(Project::getStatus, project.getStatus()) | |||||
.set(Project::getStage, project.getStage()).eq(Project::getId, req.getProjectId()); | |||||
projectService.update(update); | projectService.update(update); | ||||
} | } | ||||
@@ -169,112 +166,6 @@ public class AnnualPlanLibManage { | |||||
projectService.updateById(project); | projectService.updateById(project); | ||||
} | } | ||||
@Transactional(rollbackFor = Exception.class) | |||||
public void importAnnualPlan(ImportTemplateEnum template, MultipartFile file) { | |||||
String contentType = file.getContentType(); | |||||
if (!contentType.equals(ExcelUtil.XLS_CONTENT_TYPE) && | |||||
!contentType.equals(ExcelUtil.XLSX_CONTENT_TYPE) | |||||
) { | |||||
throw BizException.wrap("导入失败,不支持的文件类型,请按照提供的模板导入文件!"); | |||||
} | |||||
try (InputStream inputStream = file.getInputStream(); | |||||
ExcelReader reader = ExcelUtil.getReader(inputStream)) { | |||||
Map<String, String> alias; | |||||
List<String> title = ImportTemplateConstant.getTemplateTitle(template); | |||||
switch (template) { | |||||
case ANNUAL_PLAN: | |||||
alias = new HashMap<>(title.size()); | |||||
alias.put(title.get(0), "id"); | |||||
alias.put(title.get(1), "projectId"); | |||||
alias.put(title.get(2), "projectName"); | |||||
alias.put(title.get(3), "projectIntroduction"); | |||||
alias.put(title.get(4), "buildBasis"); | |||||
alias.put(title.get(5), "isFirst"); | |||||
alias.put(title.get(6), "buildCycle"); | |||||
alias.put(title.get(7), "declaredAmount"); | |||||
alias.put(title.get(8), "annualPlanAmount"); | |||||
alias.put(title.get(9), "declareHaveAmount"); | |||||
alias.put(title.get(10), "declareGovOwnFinanceAmount"); | |||||
alias.put(title.get(11), "declareGovSuperiorFinanceAmount"); | |||||
alias.put(title.get(12), "declareBankLendingAmount"); | |||||
alias.put(title.get(13), "declareOtherAmount"); | |||||
alias.put(title.get(14), "firstQuarter"); | |||||
alias.put(title.get(15), "secondQuarter"); | |||||
alias.put(title.get(16), "thirdQuarter"); | |||||
alias.put(title.get(17), "fourthQuarter"); | |||||
alias.put(title.get(18), "buildUnitName"); | |||||
alias.put(title.get(19), "contactName"); | |||||
alias.put(title.get(20), "responsibleMan"); | |||||
alias.put(title.get(21), "projectRemarks"); | |||||
reader.setHeaderAlias(alias); | |||||
importAnnualPlanData(reader.readAll(AnnualLibImportDTO.class)); | |||||
break; | |||||
default: | |||||
throw new BizException("不支持的数据导入类型"); | |||||
} | |||||
} catch (IOException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
private void importAnnualPlanData(List<AnnualLibImportDTO> importDataList) { | |||||
if (CollectionUtils.isEmpty(importDataList)) { | |||||
return; | |||||
} | |||||
List<Project> projectList = new ArrayList<>(); | |||||
List<Long> projectIds = CollUtils.fieldList(importDataList, AnnualLibImportDTO::getProjectId); | |||||
Assert.isTrue(projectIds.size() == importDataList.size(), "项目ID不可重复"); | |||||
Long userId = LoginUserUtil.getUserId(); | |||||
LocalDateTime now = LocalDateTime.now(); | |||||
importDataList.forEach(w -> { | |||||
Project project = new Project(); | |||||
project.setCreateBy(userId); | |||||
project.setCreateOn(now); | |||||
project.setUpdateBy(userId); | |||||
project.setUpdateOn(now); | |||||
project.setId(w.getProjectId()); | |||||
project.setProjectName(w.getProjectName()); | |||||
project.setProjectIntroduction(w.getProjectIntroduction()); | |||||
// 建设依据(立项依据忽略) | |||||
if (CommonConst.NEW_CONSTRUCTION.equals(w.getIsFirst())){ | |||||
project.setIsFirst(CommonEnum.YES.getCode()); | |||||
}else if (CommonConst.CONTINUED_CONSTRUCTION.equals(w.getIsFirst())){ | |||||
project.setIsFirst(CommonEnum.NO.getCode()); | |||||
} | |||||
String buildCycle = w.getBuildCycle(); | |||||
int index = buildCycle.indexOf(CommonConst.MONTH); | |||||
if (-1 == index){ | |||||
throw new BizException("项目ID为:" + w.getProjectId() + "的建设起止年限格式不正确,请按照xx年xx月至xx年xx月的格式输入!"); | |||||
} | |||||
String beginTime = buildCycle.substring(0, index + 1); | |||||
project.setBeginTime(beginTime); | |||||
String endTime = buildCycle.substring(index + 2); | |||||
project.setEndTime(endTime); | |||||
project.setDeclareAmount(w.getDeclaredAmount()); | |||||
project.setAnnualPlanAmount(w.getAnnualPlanAmount()); | |||||
project.setDeclareHaveAmount(w.getDeclareHaveAmount()); | |||||
project.setDeclareGovOwnFinanceAmount(w.getDeclareGovOwnFinanceAmount()); | |||||
project.setDeclareGovSuperiorFinanceAmount(w.getDeclareGovSuperiorFinanceAmount()); | |||||
project.setDeclareBankLendingAmount(w.getDeclareBankLendingAmount()); | |||||
project.setDeclareOtherAmount(w.getDeclareOtherAmount()); | |||||
project.setEngineeringSpeedOne(w.getFirstQuarter()); | |||||
project.setEngineeringSpeedTwo(w.getSecondQuarter()); | |||||
project.setEngineeringSpeedThree(w.getThirdQuarter()); | |||||
project.setEngineeringSpeedFour(w.getFourthQuarter()); | |||||
project.setBuildOrgName(w.getBuildUnitName()); | |||||
project.setContactName(w.getContactName()); | |||||
project.setResponsibleMan(w.getResponsibleMan()); | |||||
project.setProjectRemarks(w.getProjectRemarks()); | |||||
projectList.add(project); | |||||
}); | |||||
LambdaQueryWrapper<Project> delQuery = Wrappers.lambdaQuery(Project.class) | |||||
.in(Project::getId, projectIds); | |||||
projectService.remove(delQuery); | |||||
projectService.saveBatch(projectList); | |||||
} | |||||
public void updateAnnualPlan(ProjectDTO req) { | public void updateAnnualPlan(ProjectDTO req) { | ||||
Project project = BeanUtil.copyProperties(req, Project.class); | Project project = BeanUtil.copyProperties(req, Project.class); | ||||
projectService.updateById(project); | projectService.updateById(project); | ||||
@@ -290,20 +181,16 @@ public class AnnualPlanLibManage { | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | param.setIsTemporaryAugment(isTemporaryAugment); | ||||
param.setStatusList(CollUtils.fieldList(ANNUAL_PLAN_LIST_STATUS, ProjectStatusEnum::getCode)); | param.setStatusList(CollUtils.fieldList(ANNUAL_PLAN_LIST_STATUS, ProjectStatusEnum::getCode)); | ||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | ||||
query.eq(Project::getNewest, Boolean.TRUE); | |||||
query.orderByDesc(Project::getAnnualPlanAddTime); | query.orderByDesc(Project::getAnnualPlanAddTime); | ||||
List<Project> projects = projectService.list(query); | List<Project> projects = projectService.list(query); | ||||
ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ||||
Integer tableFlag = param.getTableFlag(); | |||||
if (Objects.isNull(tableFlag)) { | |||||
throw new BizException("请传入要导出的表格类型!"); | |||||
} | |||||
String fileName = null; | String fileName = null; | ||||
if (tableFlag == 0) { | |||||
fileName = "年度计划库编辑表"; | |||||
} else if (tableFlag == 1) { | |||||
if (CommonEnum.NO.getCode().equals(isTemporaryAugment)) { | |||||
fileName = "年度计划库列表"; | fileName = "年度计划库列表"; | ||||
} else if (CommonEnum.YES.getCode().equals(isTemporaryAugment)) { | |||||
fileName = "年度计划增补库列表"; | |||||
} | } | ||||
excelExportWriter.setFileName(fileName); | excelExportWriter.setFileName(fileName); | ||||
List<String> sheetsNames = new ArrayList<>(); | List<String> sheetsNames = new ArrayList<>(); | ||||
@@ -335,25 +222,207 @@ public class AnnualPlanLibManage { | |||||
} | } | ||||
switch (currentUserDataScope.get().getRole()) { | switch (currentUserDataScope.get().getRole()) { | ||||
case NORMAL_MEMBER: | case NORMAL_MEMBER: | ||||
//普通用户 只能看到自己单位去申报的 | |||||
// 普通用户 只能看到自己单位去申报的 | |||||
query.eq(Project::getBuildOrgCode, user.getEmpPosUnitCode()); | query.eq(Project::getBuildOrgCode, user.getEmpPosUnitCode()); | ||||
break; | break; | ||||
case COMPANY_MANAGER: | case COMPANY_MANAGER: | ||||
//单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||||
// 单位管理员 看到自己单位去申报的 + 待预审的主管单位是自己单位的项目 | |||||
query.eq(Project::getBuildOrgCode, user.getEmpPosUnitCode()); | query.eq(Project::getBuildOrgCode, user.getEmpPosUnitCode()); | ||||
break; | break; | ||||
case SUPER_ADMIN: | case SUPER_ADMIN: | ||||
//超级管理员 看到丽水全市的 并且也要判断他 同时是不是单位管理员 | |||||
// 超级管理员 看到丽水全市的 并且也要判断他 同时是不是单位管理员 | |||||
break; | break; | ||||
case REGION_MANAGER: | case REGION_MANAGER: | ||||
//区域管理员 看到自己区域的项目 | |||||
// 区域管理员 看到自己区域的项目 | |||||
query.eq(Project::getAreaCode, user.getRegionCode()); | query.eq(Project::getAreaCode, user.getRegionCode()); | ||||
break; | break; | ||||
default: | default: | ||||
//没有权限的话 就让它查不到 | |||||
// 没有权限的话 就让它查不到 | |||||
query.eq(Project::getId, "NULL"); | query.eq(Project::getId, "NULL"); | ||||
break; | break; | ||||
} | } | ||||
return user; | return user; | ||||
} | } | ||||
@Transactional(rollbackFor = Exception.class) | |||||
public void importAnnualPlan(ProjectLibFlagEnum importFlag, MultipartFile file) { | |||||
Long userId = LoginUserUtil.getUserId(); | |||||
ImportParams params = new ImportParams(); | |||||
// 标题行数 | |||||
params.setTitleRows(2); | |||||
// 从第几行开始,因为第一、二个大标题被上面的参数给占了,所以不是5 | |||||
params.setHeadRows(3); | |||||
// 表格数量 | |||||
params.setSheetNum(2); | |||||
List<AnnualLibImportDTO> list = null; | |||||
try { | |||||
list = ExcelImportUtil.importExcel(file.getInputStream(), AnnualLibImportDTO.class, params); | |||||
} catch (Exception e) { | |||||
throw new BizException(e.getMessage()); | |||||
} | |||||
// 筛选出导入的新建项目 | |||||
List<AnnualLibImportDTO> newList = | |||||
list.stream().filter(d -> CommonConst.NEW_CONSTRUCTION.equals(d.getIsFirst())).collect(Collectors.toList()); | |||||
List<Project> projectList = newList.stream().map(n -> { | |||||
Project project = new Project(); | |||||
assemblyProjectInfo(n, project); | |||||
// 根据传入标志判断是否临时增补 | |||||
if (ProjectLibFlagEnum.ANNUAL_PLAN.equals(importFlag)) { | |||||
project.setIsTemporaryAugment(CommonEnum.NO.getCode()); | |||||
} else if (ProjectLibFlagEnum.ANNUAL_PLAN_SUPPLEMENT.equals(importFlag)) { | |||||
project.setIsTemporaryAugment(CommonEnum.YES.getCode()); | |||||
} | |||||
project.setCreateBy(userId); | |||||
project.setUpdateBy(userId); | |||||
project.setCreateOn(LocalDateTime.now()); | |||||
project.setUpdateOn(LocalDateTime.now()); | |||||
return project; | |||||
}).collect(Collectors.toList()); | |||||
// 保存到项目库中 | |||||
projectService.saveBatch(projectList); | |||||
// 筛选出导入的续建项目 | |||||
List<AnnualLibImportDTO> continuedList = list.stream() | |||||
.filter(d -> CommonConst.CONTINUED_CONSTRUCTION.equals(d.getIsFirst())).collect(Collectors.toList()); | |||||
List<ProjectRenewalFundDeclaration> renewalFundDeclarationList = continuedList.stream().map(c -> { | |||||
ProjectRenewalFundDeclaration renewalFundDeclaration = new ProjectRenewalFundDeclaration(); | |||||
BeanUtils.copyProperties(c, renewalFundDeclaration); | |||||
renewalFundDeclaration.setAnnualPaymentAmount(c.getAnnualPlanAmount()); | |||||
renewalFundDeclaration.setOtherAmount(c.getDeclareOtherAmount()); | |||||
renewalFundDeclaration.setApprovalStatus(ProjectRenewalApprovalStatusEnum.PENDING.name()); | |||||
renewalFundDeclaration.setCreateOn(LocalDateTime.now()); | |||||
renewalFundDeclaration.setUpdateOn(LocalDateTime.now()); | |||||
return renewalFundDeclaration; | |||||
}).collect(Collectors.toList()); | |||||
// 保存到续建项目资金库中 | |||||
projectRenewalFundDeclarationService.saveBatch(renewalFundDeclarationList); | |||||
} | |||||
private void assemblyProjectInfo(AnnualLibImportDTO data, Project project) { | |||||
project.setId(data.getProjectId()); | |||||
project.setProjectName(data.getProjectName()); | |||||
project.setProjectIntroduction(data.getProjectIntroduction()); | |||||
// 建设依据忽略 | |||||
project.setIsFirst(CommonConst.NEW_CONSTRUCTION.equals(data.getIsFirst()) ? 1 : 0); | |||||
String[] dataArr = data.getBuildCycle().split(CommonConst.ZHI); | |||||
if (CollectionUtils.isEmpty(Arrays.asList(dataArr))) { | |||||
throw new BizException("项目ID为:" + data.getProjectId() + "的建设起止年限格式不正确,请按照xx年xx月至xx年xx月的格式输入!"); | |||||
} | |||||
project.setBeginTime(dataArr[0].trim()); | |||||
project.setEndTime(dataArr[1].trim()); | |||||
project.setDeclareAmount(data.getDeclaredAmount()); | |||||
project.setAnnualPlanAmount(data.getAnnualPlanAmount()); | |||||
project.setDeclareHaveAmount(data.getDeclareHaveAmount()); | |||||
project.setDeclareGovOwnFinanceAmount(data.getDeclareGovOwnFinanceAmount()); | |||||
project.setDeclareGovSuperiorFinanceAmount(data.getDeclareGovSuperiorFinanceAmount()); | |||||
project.setDeclareBankLendingAmount(data.getDeclareBankLendingAmount()); | |||||
project.setDeclareOtherAmount(data.getDeclareOtherAmount()); | |||||
project.setEngineeringSpeedOne(data.getFirstQuarter()); | |||||
project.setEngineeringSpeedTwo(data.getSecondQuarter()); | |||||
project.setEngineeringSpeedThree(data.getThirdQuarter()); | |||||
project.setEngineeringSpeedFour(data.getFourthQuarter()); | |||||
project.setBuildOrgName(data.getBuildUnitName()); | |||||
project.setContactName(data.getContactName()); | |||||
project.setResponsibleMan(data.getResponsibleMan()); | |||||
project.setProjectRemarks(data.getProjectRemarks()); | |||||
} | |||||
public void exportModifyList(ProjectListReq param, HttpServletResponse response) { | |||||
int year = LocalDateTime.now().getYear(); | |||||
Integer isTemporaryAugment = param.getIsTemporaryAugment(); | |||||
if (Objects.isNull(isTemporaryAugment)) { | |||||
throw new BizException("请传入是否临时增补标志!"); | |||||
} | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
String fileName = null; | |||||
// 设置excel的文件名称和是否增补 | |||||
if (CommonEnum.NO.getCode().equals(isTemporaryAugment)) { | |||||
fileName = "丽水市" + year + "年数字化项目年度计划库编辑表"; | |||||
} else if (CommonEnum.YES.getCode().equals(isTemporaryAugment)) { | |||||
fileName = "丽水市" + year + "年数字化项目年度计划增补库编辑表"; | |||||
} | |||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | |||||
query.eq(Project::getIsTemporaryAugment, isTemporaryAugment); | |||||
query.orderByDesc(Project::getAnnualPlanAddTime); | |||||
query.in(Project::getStatus, CollUtils.fieldList(ANNUAL_PLAN_LIST_STATUS, ProjectStatusEnum::getCode)); | |||||
// 数据权限 | |||||
buildProjectLibPermission(query); | |||||
List<Project> projects = projectService.list(query); | |||||
List<AnnualLibExportDTO> list = projects.stream().map(p -> { | |||||
AnnualLibExportDTO dto = new AnnualLibExportDTO(); | |||||
BeanUtils.copyProperties(p, dto); | |||||
String beginTime = p.getBeginTime(); | |||||
String begin = beginTime.replace(StrPool.DASH, CommonConst.YEAR); | |||||
begin = begin + CommonConst.MONTH; | |||||
String endTime = p.getEndTime(); | |||||
String end = endTime.replace(StrPool.DASH, CommonConst.YEAR); | |||||
end = end + CommonConst.MONTH; | |||||
String buildCycle = begin + CommonConst.ZHI + end; | |||||
dto.setBuildCycle(buildCycle); | |||||
dto.setProjectId(p.getId()); | |||||
dto.setDeclaredAmount(p.getDeclareAmount()); | |||||
dto.setBuildUnitName(p.getBuildOrgName()); | |||||
String buildBasis = p.getBuildBasis(); | |||||
List<JSONObject> fileArray = JSON.parseArray(buildBasis, JSONObject.class); | |||||
List<String> nameList = CollUtils.fieldList(fileArray, w -> w.getString(CommonConst.TITLE) | |||||
+ StrPool.LEFT_BRACKET + w.getString(CommonConst.BASIS_FILE_NAME) + StrPool.RIGHT_BRACKET); | |||||
String basis = nameList.stream().collect(Collectors.joining(StrPool.COMMA)); | |||||
dto.setBuildBasis(basis); | |||||
if (CommonEnum.YES.getCode().equals(p.getIsFirst())) { | |||||
dto.setIsFirst(CommonConst.NEW_CONSTRUCTION); | |||||
} else if (CommonEnum.NO.getCode().equals(p.getIsFirst())) { | |||||
dto.setIsFirst(CommonConst.CONTINUED_CONSTRUCTION); | |||||
} | |||||
dto.setFirstQuarter(p.getEngineeringSpeedOne()); | |||||
dto.setSecondQuarter(p.getEngineeringSpeedTwo()); | |||||
dto.setThirdQuarter(p.getEngineeringSpeedThree()); | |||||
dto.setFourthQuarter(p.getEngineeringSpeedFour()); | |||||
return dto; | |||||
}).collect(Collectors.toList()); | |||||
int count = 0; | |||||
for (AnnualLibExportDTO annualLibExportDTO : list) { | |||||
count++; | |||||
annualLibExportDTO.setSerialNumber(count); | |||||
} | |||||
// 获取本地目录的年度计划编辑表Excel模板 | |||||
File directory = new File(""); | |||||
String templateName = "丽水市" + year + "年数字化项目年度计划编辑表"; | |||||
String templatePath = | |||||
directory.getAbsolutePath() + File.separator + "template" + File.separator + templateName + ".xls"; | |||||
TemplateExportParams temp = new TemplateExportParams(templatePath); | |||||
temp.setSheetNum(new Integer[] {0, 1}); | |||||
temp.setSheetName(new String[] {"实施类(新建)", "实施类(续建)"}); | |||||
Map<String, Object> map = new HashMap<>(4); | |||||
map.put("mapList", list); | |||||
map.put("mapList1", null); | |||||
Workbook workbook = ExcelExportUtil.exportExcel(temp, map); | |||||
if (workbook == null) { | |||||
throw new BizException("读取模板失败!"); | |||||
} | |||||
// 重置响应对象 | |||||
response.reset(); | |||||
try { | |||||
response.setHeader("Content-disposition", | |||||
"attachment;filename*=utf-8''" + URLEncoder.encode(Objects.requireNonNull(fileName), "UTF-8") + ".xls"); | |||||
} catch (UnsupportedEncodingException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
response.setContentType(ExcelUtil.XLS_CONTENT_TYPE); | |||||
response.setHeader("Pragma", "no-cache"); | |||||
response.setHeader("Cache-Control", "no-cache"); | |||||
response.setDateHeader("Expires", 0); | |||||
// 写出数据输出流到页面 | |||||
try { | |||||
OutputStream output = response.getOutputStream(); | |||||
BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output); | |||||
workbook.write(bufferedOutPut); | |||||
bufferedOutPut.flush(); | |||||
bufferedOutPut.close(); | |||||
output.close(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | } |
@@ -1,38 +1,47 @@ | |||||
package com.ningdatech.pmapi.projectlib.manage; | package com.ningdatech.pmapi.projectlib.manage; | ||||
import cn.hutool.core.bean.BeanUtil; | |||||
import cn.hutool.core.bean.copier.CopyOptions; | |||||
import cn.hutool.core.collection.CollUtil; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||
import com.ningdatech.basic.function.VUtils; | |||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
import com.ningdatech.basic.util.CollUtils; | import com.ningdatech.basic.util.CollUtils; | ||||
import com.ningdatech.file.entity.File; | import com.ningdatech.file.entity.File; | ||||
import com.ningdatech.file.service.FileService; | import com.ningdatech.file.service.FileService; | ||||
import com.ningdatech.pmapi.common.constant.CommonConst; | import com.ningdatech.pmapi.common.constant.CommonConst; | ||||
import com.ningdatech.pmapi.common.constant.RegionConst; | import com.ningdatech.pmapi.common.constant.RegionConst; | ||||
import com.ningdatech.pmapi.common.enumeration.CommonEnum; | |||||
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | |||||
import com.ningdatech.pmapi.common.helper.RegionCacheHelper; | import com.ningdatech.pmapi.common.helper.RegionCacheHelper; | ||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | import com.ningdatech.pmapi.common.helper.UserInfoHelper; | ||||
import com.ningdatech.pmapi.common.model.entity.ExcelExportWriter; | import com.ningdatech.pmapi.common.model.entity.ExcelExportWriter; | ||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||||
import com.ningdatech.pmapi.common.util.BizUtils; | import com.ningdatech.pmapi.common.util.BizUtils; | ||||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | import com.ningdatech.pmapi.common.util.ExcelDownUtil; | ||||
import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | import com.ningdatech.pmapi.datascope.model.DataScopeDTO; | ||||
import com.ningdatech.pmapi.datascope.utils.DataScopeUtil; | import com.ningdatech.pmapi.datascope.utils.DataScopeUtil; | ||||
import com.ningdatech.pmapi.projectdeclared.utils.GenerateProjectCodeUtil; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import com.ningdatech.pmapi.projectlib.handle.ProcessExecuteChainHandle; | import com.ningdatech.pmapi.projectlib.handle.ProcessExecuteChainHandle; | ||||
import com.ningdatech.pmapi.projectlib.helper.ProjectHelper; | import com.ningdatech.pmapi.projectlib.helper.ProjectHelper; | ||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectApplicationDTO; | |||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectRenewalFundDeclaration; | import com.ningdatech.pmapi.projectlib.model.entity.ProjectRenewalFundDeclaration; | ||||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | ||||
import com.ningdatech.pmapi.projectlib.model.vo.AnnualAmountVO; | import com.ningdatech.pmapi.projectlib.model.vo.AnnualAmountVO; | ||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | ||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | ||||
import com.ningdatech.pmapi.projectlib.service.INdProjectStatusChangeService; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectRenewalFundDeclarationService; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import com.ningdatech.pmapi.projectlib.service.*; | |||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import com.wflow.exception.BusinessException; | |||||
import com.wflow.workflow.bean.vo.ProcessDetailVO; | import com.wflow.workflow.bean.vo.ProcessDetailVO; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
@@ -41,7 +50,9 @@ import org.springframework.beans.BeanUtils; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
import java.time.LocalDateTime; | |||||
import java.util.*; | import java.util.*; | ||||
import java.util.stream.Collectors; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
@@ -60,14 +71,18 @@ public class ProjectLibManage { | |||||
private final IProjectApplicationService applicationService; | private final IProjectApplicationService applicationService; | ||||
private final IProjectRenewalFundDeclarationService renewalFundDeclarationService; | private final IProjectRenewalFundDeclarationService renewalFundDeclarationService; | ||||
private final ProcessExecuteChainHandle processExecuteHandle; | private final ProcessExecuteChainHandle processExecuteHandle; | ||||
private final INdProjectStatusChangeService projectStatusChangeService; | |||||
private final RegionCacheHelper regionCacheHelper; | private final RegionCacheHelper regionCacheHelper; | ||||
private final FileService fileService; | private final FileService fileService; | ||||
private final UserInfoHelper userInfoHelper; | private final UserInfoHelper userInfoHelper; | ||||
private final IProjectApplicationService projectApplicationService; | |||||
private final GenerateProjectCodeUtil generateProjectCodeUtil; | |||||
private final IProjectInstService projectInstService; | |||||
private final StateMachineUtils stateMachineUtils; | |||||
public PageVo<ProjectLibListItemVO> projectLibList(ProjectListReq req) { | public PageVo<ProjectLibListItemVO> projectLibList(ProjectListReq req) { | ||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | ||||
query.eq(Project::getNewest,Boolean.TRUE); | |||||
Page<Project> page = projectService.page(req.page(), query); | Page<Project> page = projectService.page(req.page(), query); | ||||
long total; | long total; | ||||
if ((total = page.getTotal()) == 0) { | if ((total = page.getTotal()) == 0) { | ||||
@@ -96,6 +111,8 @@ public class ProjectLibManage { | |||||
public PageVo<ProjectLibListItemVO> projectLibListWithPermission(ProjectListReq req) { | public PageVo<ProjectLibListItemVO> projectLibListWithPermission(ProjectListReq req) { | ||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | ||||
UserFullInfoDTO user = buildProjectLibPermission(query); | UserFullInfoDTO user = buildProjectLibPermission(query); | ||||
//项目查最新 | |||||
query.eq(Project::getNewest,Boolean.TRUE); | |||||
Page<Project> page = projectService.page(req.page(), query); | Page<Project> page = projectService.page(req.page(), query); | ||||
long total; | long total; | ||||
if ((total = page.getTotal()) == 0) { | if ((total = page.getTotal()) == 0) { | ||||
@@ -133,6 +150,187 @@ public class ProjectLibManage { | |||||
} | } | ||||
/** | /** | ||||
* 申报新项目时 保存项目信息和其它相关联的信息 | |||||
* @param projectDto | |||||
* @param instanceId | |||||
* @param employeeCode | |||||
* @return | |||||
*/ | |||||
public Project saveProjectInDeclared(ProjectDTO projectDto, String instanceId, | |||||
String employeeCode) { | |||||
Project project = saveProjectNewVersion(projectDto,instanceId,employeeCode); | |||||
//保存项目和实例的关系 | |||||
ProjectInst projectInst = new ProjectInst(); | |||||
projectInst.setProjectId(project.getId()); | |||||
projectInst.setInstCode(instanceId); | |||||
projectInst.setCreatOn(LocalDateTime.now()); | |||||
projectInst.setUpdateOn(LocalDateTime.now()); | |||||
projectInst.setInstType(ProjectProcessStageEnum.ORG_INTERNAL_APPROVAL_PROCESS.getCode()); | |||||
projectInstService.save(projectInst); | |||||
return project; | |||||
} | |||||
/** | |||||
* 申报新项目时 保存项目信息和其它相关联的信息 | |||||
* @param projectDto | |||||
* @param instanceId | |||||
* @param employeeCode | |||||
* @return | |||||
*/ | |||||
public Project saveProjectNewVersion(ProjectDTO projectDto, String instanceId, | |||||
String employeeCode) { | |||||
//流程启动之后 入库项目 重要业务信息 用于列表查询 展示 | |||||
try { | |||||
Project project = new Project(); | |||||
//为空 代表是新申报的 | |||||
if(Objects.isNull(projectDto.getId())){ | |||||
BeanUtils.copyProperties(projectDto, project); | |||||
project.setCreateOn(LocalDateTime.now()); | |||||
project.setUpdateOn(LocalDateTime.now()); | |||||
project.setStage(ProjectStatusEnum.NOT_APPROVED.getCode()); | |||||
project.setStatus(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode()); | |||||
project.setInstCode(instanceId); | |||||
project.setSponsor(employeeCode); | |||||
String projectCode = generateProjectCodeUtil.generateProjectCode(projectDto); | |||||
project.setProjectCode(projectCode); | |||||
projectService.save(project); | |||||
}else{ | |||||
//否则是重新提交的 新生成一个新版本的项目 | |||||
project = newProjectWithVersion(projectDto); | |||||
project.setInstCode(instanceId); | |||||
project.setSponsor(employeeCode); | |||||
projectService.updateById(project); | |||||
} | |||||
//保存项目应用 | |||||
Boolean isApp = Objects.nonNull(projectDto.getIncludeApplication()) && CommonEnum.YES.getCode().equals(projectDto.getIncludeApplication()) | |||||
? Boolean.TRUE : Boolean.FALSE; | |||||
//采取批量删除 批量添加的方式 | |||||
projectApplicationService.remove(Wrappers.lambdaQuery(ProjectApplication.class) | |||||
.eq(ProjectApplication::getProjectId,project.getId())); | |||||
if (isApp && CollUtil.isNotEmpty(projectDto.getApplicationList())) { | |||||
Project finalProject = project; | |||||
List<ProjectApplication> applications = projectDto.getApplicationList().stream().map(application -> { | |||||
ProjectApplication projectApplication = new ProjectApplication(); | |||||
BeanUtils.copyProperties(application, projectApplication); | |||||
projectApplication.setProjectId(finalProject.getId()); | |||||
return projectApplication; | |||||
}).collect(Collectors.toList()); | |||||
projectApplicationService.saveOrUpdateBatch(applications); | |||||
} | |||||
return project; | |||||
} catch (Exception e) { | |||||
log.error("项目信息入库错误 " + e); | |||||
throw new BusinessException("项目信息入库错误 :" + e); | |||||
} | |||||
} | |||||
/** | |||||
* 在其它项目阶段 保存项目信息和其它相关联的信息 | |||||
* @param projectDto | |||||
* @return | |||||
*/ | |||||
public Project reSaveProjectNewVersion(ProjectDTO projectDto) { | |||||
//流程启动之后 入库项目 重要业务信息 用于列表查询 展示 | |||||
try { | |||||
Project project = newProjectWithVersion(projectDto); | |||||
//保存项目应用 | |||||
Boolean isApp = Objects.nonNull(projectDto.getIncludeApplication()) && CommonEnum.YES.getCode().equals(projectDto.getIncludeApplication()) | |||||
? Boolean.TRUE : Boolean.FALSE; | |||||
//采取批量删除 批量添加的方式 | |||||
projectApplicationService.remove(Wrappers.lambdaQuery(ProjectApplication.class) | |||||
.eq(ProjectApplication::getProjectId,project.getId())); | |||||
if (isApp && CollUtil.isNotEmpty(projectDto.getApplicationList())) { | |||||
Project finalProject = project; | |||||
List<ProjectApplication> applications = projectDto.getApplicationList().stream().map(application -> { | |||||
ProjectApplication projectApplication = new ProjectApplication(); | |||||
BeanUtils.copyProperties(application, projectApplication); | |||||
projectApplication.setProjectId(finalProject.getId()); | |||||
return projectApplication; | |||||
}).collect(Collectors.toList()); | |||||
projectApplicationService.saveOrUpdateBatch(applications); | |||||
} | |||||
return project; | |||||
} catch (Exception e) { | |||||
log.error("项目信息入库错误 " + e); | |||||
throw new BusinessException("项目信息入库错误 :" + e); | |||||
} | |||||
} | |||||
/** | |||||
* 重新提交工作流时 舍弃在原有项目修改 | |||||
* 新增一个新的项目 新的版本号 | |||||
*/ | |||||
public Project newProjectWithVersion(ProjectDTO projecDto){ | |||||
Project oldProject = projectService.getById(projecDto.getId()); | |||||
Project project = new Project(); | |||||
VUtils.isTrue(Objects.isNull(oldProject)) | |||||
.throwMessage("项目不存在!"); | |||||
BeanUtil.copyProperties(oldProject,project, CopyOptions.create() | |||||
.setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE)); | |||||
BeanUtil.copyProperties(projecDto,project, CopyOptions.create() | |||||
.setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE)); | |||||
project.setVersion(oldProject.getVersion() + 1); | |||||
project.setId(null); | |||||
project.setCreateOn(LocalDateTime.now()); | |||||
project.setUpdateOn(LocalDateTime.now()); | |||||
stateMachineUtils.pass(project); | |||||
projectService.save(project); | |||||
projectService.update(Wrappers.lambdaUpdate(Project.class) | |||||
.set(Project::getNewest,Boolean.FALSE) | |||||
.ne(Project::getId,project.getId()) | |||||
.eq(Project::getProjectCode,project.getProjectCode())); | |||||
return project; | |||||
} | |||||
public Project saveProjectWithVersionAndStatus(ProjectDTO projecDto,Integer stageCode,Integer statusCode){ | |||||
Project oldProject = projectService.getById(projecDto.getId()); | |||||
Project project = new Project(); | |||||
VUtils.isTrue(Objects.isNull(oldProject)) | |||||
.throwMessage("项目不存在!"); | |||||
BeanUtil.copyProperties(oldProject,project, CopyOptions.create() | |||||
.setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE)); | |||||
BeanUtil.copyProperties(projecDto,project, CopyOptions.create() | |||||
.setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE)); | |||||
project.setVersion(oldProject.getVersion() + 1); | |||||
project.setId(null); | |||||
project.setCreateOn(LocalDateTime.now()); | |||||
project.setUpdateOn(LocalDateTime.now()); | |||||
if(Objects.nonNull(stageCode)){ | |||||
project.setStage(stageCode); | |||||
} | |||||
if(Objects.nonNull(statusCode)){ | |||||
project.setStatus(statusCode); | |||||
} | |||||
if(projectService.save(project)){ | |||||
projectService.update(Wrappers.lambdaUpdate(Project.class) | |||||
.set(Project::getNewest,Boolean.FALSE) | |||||
.ne(Project::getId,project.getId()) | |||||
.eq(Project::getProjectCode,project.getProjectCode())); | |||||
//app | |||||
List<ProjectApplicationDTO> applicationList = projecDto.getApplicationList(); | |||||
if(CollUtil.isNotEmpty(applicationList)){ | |||||
List<ProjectApplication> apps = applicationList.stream() | |||||
.map(a -> { | |||||
ProjectApplication app = BeanUtil.copyProperties(a,ProjectApplication.class); | |||||
app.setId(null); | |||||
app.setProjectId(project.getId()); | |||||
return app; | |||||
}) | |||||
.collect(Collectors.toList()); | |||||
projectApplicationService.saveBatch(apps); | |||||
} | |||||
} | |||||
return project; | |||||
} | |||||
/** | |||||
* @param projectId 项目详情 | * @param projectId 项目详情 | ||||
* @return com.ningdatech.pmapi.projectlib.model.entity.vo.ProjectDetailVO | * @return com.ningdatech.pmapi.projectlib.model.entity.vo.ProjectDetailVO | ||||
* @author ZPF | * @author ZPF | ||||
@@ -199,6 +397,7 @@ public class ProjectLibManage { | |||||
param.setPageNumber(CommonConst.EXPORT_PAGE_NUMBER); | param.setPageNumber(CommonConst.EXPORT_PAGE_NUMBER); | ||||
param.setPageSize(CommonConst.EXPORT_PAGE_SIZE); | param.setPageSize(CommonConst.EXPORT_PAGE_SIZE); | ||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | ||||
query.eq(Project::getNewest,Boolean.TRUE); | |||||
List<Project> projects = projectService.list(query); | List<Project> projects = projectService.list(query); | ||||
ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ||||
@@ -271,4 +470,8 @@ public class ProjectLibManage { | |||||
} | } | ||||
return user; | return user; | ||||
} | } | ||||
private void copyProperties(ProjectDTO projecDto, Project project) { | |||||
} | |||||
} | } |
@@ -0,0 +1,102 @@ | |||||
package com.ningdatech.pmapi.projectlib.model.dto; | |||||
import java.math.BigDecimal; | |||||
import javax.validation.constraints.NotBlank; | |||||
import javax.validation.constraints.NotNull; | |||||
import cn.afterturn.easypoi.excel.annotation.Excel; | |||||
import lombok.Data; | |||||
/** | |||||
* <p> | |||||
* AnnualLibImportDTO | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 13:46 2023/2/13 | |||||
*/ | |||||
@Data | |||||
public class AnnualLibExportDTO { | |||||
@NotNull(message = "年度投资额不能为空") | |||||
@Excel(name = "年度投资额",groupName = "2023年计划") | |||||
private BigDecimal annualPlanAmount; | |||||
@NotNull(message = "自由资金不能为空") | |||||
@Excel(name = "自有资金",groupName = "资金来源") | |||||
private BigDecimal declareHaveAmount; | |||||
@Excel(name = "政府投资-本级财政资金") | |||||
@NotNull(message = "政府投资-本级财政不能为空") | |||||
private BigDecimal declareGovOwnFinanceAmount; | |||||
@Excel(name = "政府投资-上级补助资金") | |||||
@NotNull(message = "政府投资-上级补助资金不能为空") | |||||
private BigDecimal declareGovSuperiorFinanceAmount; | |||||
@Excel(name = "银行贷款") | |||||
@NotNull(message = "银行贷款不能为空") | |||||
private BigDecimal declareBankLendingAmount; | |||||
@Excel(name = "其他") | |||||
@NotNull(message = "其他不能为空") | |||||
private BigDecimal declareOtherAmount; | |||||
@Excel(name = "一季度",groupName = "进度和支付计划") | |||||
@NotBlank(message = "一季度不能为空") | |||||
private String firstQuarter; | |||||
@Excel(name = "二季度") | |||||
@NotBlank(message = "二季度不能为空") | |||||
private String secondQuarter; | |||||
@Excel(name = "三季度") | |||||
@NotBlank(message = "三季度不能为空") | |||||
private String thirdQuarter; | |||||
@Excel(name = "四季度") | |||||
@NotBlank(message = "四季度不能为空") | |||||
private String fourthQuarter; | |||||
@NotNull(message = "序号不能为空") | |||||
@Excel(name = "序号") | |||||
private Integer serialNumber; | |||||
@Excel(name = "项目id") | |||||
@NotNull(message = "项目ID不能为空") | |||||
private Long projectId; | |||||
@Excel(name = "项目名称") | |||||
@NotBlank(message = "项目名称不能为空") | |||||
private String projectName; | |||||
@NotBlank(message = "建设内容不能为空") | |||||
@Excel(name = "建设内容") | |||||
private String projectIntroduction; | |||||
@NotBlank(message = "建设依据不能为空") | |||||
@Excel(name = "建设依据") | |||||
private String buildBasis; | |||||
@Excel(name = "建设性质") | |||||
@NotBlank(message = "建设性质不能为空") | |||||
private String isFirst; | |||||
@Excel(name = "建设起止年限(填写到月)") | |||||
@NotBlank(message = "建设起止年限不能为空") | |||||
private String buildCycle; | |||||
@NotBlank(message = "总投资不能为空") | |||||
@Excel(name = "总投资") | |||||
private BigDecimal declaredAmount; | |||||
@Excel(name = "建设单位") | |||||
@NotBlank(message = "建设单位不能为空") | |||||
private String buildUnitName; | |||||
@Excel(name = "项目联系人") | |||||
@NotBlank(message = "项目联系人不能为空") | |||||
private String contactName; | |||||
@Excel(name = "项目分管领导") | |||||
@NotBlank(message = "项目分管领导不能为空") | |||||
private String responsibleMan; | |||||
@Excel(name = "备注") | |||||
private String projectRemarks; | |||||
} |
@@ -1,5 +1,6 @@ | |||||
package com.ningdatech.pmapi.projectlib.model.dto; | package com.ningdatech.pmapi.projectlib.model.dto; | ||||
import cn.afterturn.easypoi.excel.annotation.Excel; | |||||
import com.alibaba.excel.annotation.ExcelProperty; | import com.alibaba.excel.annotation.ExcelProperty; | ||||
import lombok.Data; | import lombok.Data; | ||||
@@ -18,91 +19,104 @@ import java.math.BigDecimal; | |||||
@Data | @Data | ||||
public class AnnualLibImportDTO { | public class AnnualLibImportDTO { | ||||
@ExcelProperty("序号") | |||||
@NotNull(message = "序号不能为空") | |||||
private Integer serialNumber; | |||||
@ExcelProperty("项目id") | |||||
@NotNull(message = "项目ID不能为空") | |||||
private Long projectId; | |||||
@ExcelProperty("项目名称") | |||||
@NotBlank(message = "项目名称不能为空") | |||||
private String projectName; | |||||
@NotBlank(message = "建设内容不能为空") | |||||
@ExcelProperty("建设内容") | |||||
private String projectIntroduction; | |||||
@NotBlank(message = "建设依据不能为空") | |||||
@ExcelProperty("建设依据") | |||||
private String buildBasis; | |||||
@ExcelProperty("建设性质") | |||||
@NotBlank(message = "建设性质不能为空") | |||||
private String isFirst; | |||||
@ExcelProperty("建设起止年限") | |||||
@NotBlank(message = "建设起止年限不能为空") | |||||
private String buildCycle; | |||||
@NotBlank(message = "总投资不能为空") | |||||
@ExcelProperty("总投资") | |||||
private BigDecimal declaredAmount; | |||||
@Excel(name = "项目进展",groupName = "到2022年底完成情况") | |||||
@NotNull(message = "项目进展不能为空") | |||||
private String projectProgress; | |||||
@Excel(name = "累计投资") | |||||
@NotNull(message = "累计投资不能为空") | |||||
private BigDecimal cumulativeInvest; | |||||
@NotNull(message = "年度投资额不能为空") | @NotNull(message = "年度投资额不能为空") | ||||
@ExcelProperty("年度投资额") | |||||
@Excel(name = "年度投资额",groupName = "2023年计划") | |||||
private BigDecimal annualPlanAmount; | private BigDecimal annualPlanAmount; | ||||
@ExcelProperty("自有资金") | |||||
@NotNull(message = "自由资金不能为空") | @NotNull(message = "自由资金不能为空") | ||||
@Excel(name = "自有资金",groupName = "资金来源") | |||||
private BigDecimal declareHaveAmount; | private BigDecimal declareHaveAmount; | ||||
@ExcelProperty("政府投资-本级财政") | |||||
@Excel(name = "政府投资-本级财政资金") | |||||
@NotNull(message = "政府投资-本级财政不能为空") | @NotNull(message = "政府投资-本级财政不能为空") | ||||
private BigDecimal declareGovOwnFinanceAmount; | private BigDecimal declareGovOwnFinanceAmount; | ||||
@ExcelProperty("政府投资-上级补助资金") | |||||
@Excel(name = "政府投资-上级补助资金") | |||||
@NotNull(message = "政府投资-上级补助资金不能为空") | @NotNull(message = "政府投资-上级补助资金不能为空") | ||||
private BigDecimal declareGovSuperiorFinanceAmount; | private BigDecimal declareGovSuperiorFinanceAmount; | ||||
@ExcelProperty("银行贷款") | |||||
@Excel(name = "银行贷款") | |||||
@NotNull(message = "银行贷款不能为空") | @NotNull(message = "银行贷款不能为空") | ||||
private BigDecimal declareBankLendingAmount; | private BigDecimal declareBankLendingAmount; | ||||
@ExcelProperty("其他") | |||||
@Excel(name = "国家、省补助",groupName = "资金来源") | |||||
@NotNull(message = "国家、省补助不能为空") | |||||
private BigDecimal govSuperiorFinanceAmount; | |||||
@Excel(name = "地方财政统筹") | |||||
@NotNull(message = "地方财政统筹不能为空") | |||||
private BigDecimal govOwnFinanceAmount; | |||||
@Excel(name = "建设单位自筹") | |||||
@NotNull(message = "建设单位自筹不能为空") | |||||
private BigDecimal haveAmount; | |||||
@Excel(name = "其他") | |||||
@NotNull(message = "其他不能为空") | @NotNull(message = "其他不能为空") | ||||
private BigDecimal declareOtherAmount; | private BigDecimal declareOtherAmount; | ||||
@ExcelProperty("一季度") | |||||
@Excel(name = "一季度",groupName = "进度和支付计划") | |||||
@NotBlank(message = "一季度不能为空") | @NotBlank(message = "一季度不能为空") | ||||
private String firstQuarter; | private String firstQuarter; | ||||
@ExcelProperty("二季度") | |||||
@Excel(name = "二季度") | |||||
@NotBlank(message = "二季度不能为空") | @NotBlank(message = "二季度不能为空") | ||||
private String secondQuarter; | private String secondQuarter; | ||||
@ExcelProperty("三季度") | |||||
@Excel(name = "三季度") | |||||
@NotBlank(message = "三季度不能为空") | @NotBlank(message = "三季度不能为空") | ||||
private String thirdQuarter; | private String thirdQuarter; | ||||
@ExcelProperty("四季度") | |||||
@Excel(name = "四季度") | |||||
@NotBlank(message = "四季度不能为空") | @NotBlank(message = "四季度不能为空") | ||||
private String fourthQuarter; | private String fourthQuarter; | ||||
@ExcelProperty("建设单位") | |||||
@NotNull(message = "序号不能为空") | |||||
@Excel(name = "序号") | |||||
private Integer serialNumber; | |||||
@Excel(name = "项目id") | |||||
@NotNull(message = "项目ID不能为空") | |||||
private Long projectId; | |||||
@Excel(name = "项目名称") | |||||
@NotBlank(message = "项目名称不能为空") | |||||
private String projectName; | |||||
@NotBlank(message = "建设内容不能为空") | |||||
@Excel(name = "建设内容") | |||||
private String projectIntroduction; | |||||
@NotBlank(message = "建设依据不能为空") | |||||
@Excel(name = "建设依据") | |||||
private String buildBasis; | |||||
@Excel(name = "建设性质") | |||||
@NotBlank(message = "建设性质不能为空") | |||||
private String isFirst; | |||||
@Excel(name = "建设周期") | |||||
@NotBlank(message = "建设周期不能为空") | |||||
private String constructionCycle; | |||||
@Excel(name = "建设起止年限(填写到月)") | |||||
@NotBlank(message = "建设起止年限不能为空") | |||||
private String buildCycle; | |||||
@NotBlank(message = "总投资不能为空") | |||||
@Excel(name = "总投资") | |||||
private BigDecimal declaredAmount; | |||||
@Excel(name = "建设单位") | |||||
@NotBlank(message = "建设单位不能为空") | @NotBlank(message = "建设单位不能为空") | ||||
private String buildUnitName; | private String buildUnitName; | ||||
@ExcelProperty("项目联系人") | |||||
@Excel(name = "项目联系人") | |||||
@NotBlank(message = "项目联系人不能为空") | @NotBlank(message = "项目联系人不能为空") | ||||
private String contactName; | private String contactName; | ||||
@ExcelProperty("项目分管领导") | |||||
@Excel(name = "项目分管领导") | |||||
@NotBlank(message = "项目分管领导不能为空") | @NotBlank(message = "项目分管领导不能为空") | ||||
private String responsibleMan; | private String responsibleMan; | ||||
@ExcelProperty("备注") | |||||
@Excel(name = "备注") | |||||
private String projectRemarks; | private String projectRemarks; | ||||
} | } |
@@ -282,6 +282,9 @@ public class ProjectDTO implements Serializable { | |||||
@ApiModelProperty("项目发起人 员工code") | @ApiModelProperty("项目发起人 员工code") | ||||
private String sponsor; | private String sponsor; | ||||
@ApiModelProperty("预审发起人 员工code") | |||||
private String preStartUserId; | |||||
@ApiModelProperty("上级条线单位审核意见") | @ApiModelProperty("上级条线单位审核意见") | ||||
private String higherLineSuperOrgReviewComments; | private String higherLineSuperOrgReviewComments; | ||||
@@ -0,0 +1,92 @@ | |||||
package com.ningdatech.pmapi.projectlib.model.entity; | |||||
import com.alibaba.excel.context.AnalysisContext; | |||||
import com.alibaba.excel.event.AnalysisEventListener; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.ningdatech.basic.exception.BizException; | |||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.ningdatech.pmapi.common.constant.CommonConst; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
import lombok.NoArgsConstructor; | |||||
import lombok.RequiredArgsConstructor; | |||||
import java.util.*; | |||||
/** | |||||
* @author CMM | |||||
* @since 2023/04/17 18:26 | |||||
*/ | |||||
@Data | |||||
public class AnalysisEventMonitor extends AnalysisEventListener<Map<Integer, String>> { | |||||
private final List<Project> records = new ArrayList<>(); | |||||
/** | |||||
* 存储Key | |||||
*/ | |||||
Map<Integer, String> key = new HashMap<>(); | |||||
/** | |||||
* keyList | |||||
*/ | |||||
List<String> keyList = new ArrayList<>(); | |||||
@Override | |||||
public void onException(Exception exception, AnalysisContext context) throws Exception { | |||||
super.onException(exception, context); | |||||
throw BizException.wrap("导入年度计划解析失败"); | |||||
} | |||||
@Override | |||||
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { | |||||
Set<Integer> integerSet = headMap.keySet(); | |||||
for (Integer integer : integerSet) { | |||||
keyList.add(headMap.get(integer)); | |||||
} | |||||
key.putAll(headMap); | |||||
} | |||||
@Override | |||||
public void invoke(Map<Integer, String> integerStringMap, AnalysisContext context) { | |||||
//Project project = new Project(); | |||||
//project.setId(data.getProjectId()); | |||||
//project.setProjectName(data.getProjectName()); | |||||
//project.setProjectIntroduction(data.getProjectIntroduction()); | |||||
//// 建设依据忽略 | |||||
//project.setIsFirst(CommonConst.NEW_CONSTRUCTION.equals(data.getIsFirst()) ? 1 : 0); | |||||
//String[] dataArr = data.getBuildCycle().split(CommonConst.ZHI); | |||||
//project.setBeginTime(dataArr[0].trim()); | |||||
//project.setEndTime(dataArr[1].trim()); | |||||
//project.setDeclareAmount(data.getDeclaredAmount()); | |||||
//project.setAnnualPlanAmount(data.getAnnualPlanAmount()); | |||||
//project.setDeclareHaveAmount(data.getDeclareHaveAmount()); | |||||
//project.setDeclareGovOwnFinanceAmount(data.getDeclareGovOwnFinanceAmount()); | |||||
//project.setDeclareGovSuperiorFinanceAmount(data.getDeclareGovSuperiorFinanceAmount()); | |||||
//project.setDeclareBankLendingAmount(data.getDeclareBankLendingAmount()); | |||||
//project.setDeclareOtherAmount(data.getDeclareOtherAmount()); | |||||
//project.setEngineeringSpeedOne(data.getFirstQuarter()); | |||||
//project.setEngineeringSpeedTwo(data.getSecondQuarter()); | |||||
//project.setEngineeringSpeedThree(data.getThirdQuarter()); | |||||
//project.setEngineeringSpeedFour(data.getFourthQuarter()); | |||||
//project.setBuildOrgName(data.getBuildUnitName()); | |||||
//project.setContactName(data.getContactName()); | |||||
//project.setResponsibleMan(data.getResponsibleMan()); | |||||
//project.setProjectRemarks(data.getProjectRemarks()); | |||||
//records.add(project); | |||||
} | |||||
@Override | |||||
public void doAfterAllAnalysed(AnalysisContext context) { | |||||
//if (records.isEmpty()) { | |||||
// throw BizException.wrap("导入年度计划为空"); | |||||
//} | |||||
//List<Long> projectIds = CollUtils.fieldList(records, Project::getId); | |||||
//long count = projectService.count(Wrappers.lambdaQuery(Project.class) | |||||
// .in(Project::getId, projectIds)); | |||||
//if (count != records.size()) { | |||||
// throw BizException.wrap("请确保所有项目都存在"); | |||||
//} | |||||
//projectService.updateBatchById(records); | |||||
} | |||||
} |
@@ -324,4 +324,9 @@ public class Project implements Serializable { | |||||
@ApiModelProperty("省级联审 审批结果") | @ApiModelProperty("省级联审 审批结果") | ||||
private String sjlsResult; | private String sjlsResult; | ||||
@ApiModelProperty("版本号") | |||||
private Integer version; | |||||
@ApiModelProperty("是否是最新版本") | |||||
private Boolean newest; | |||||
} | } |
@@ -2,12 +2,12 @@ package com.ningdatech.pmapi.projectlib.model.req; | |||||
import com.ningdatech.basic.model.PagePo; | import com.ningdatech.basic.model.PagePo; | ||||
import com.ningdatech.pmapi.common.enumeration.ExportOptionEnum; | import com.ningdatech.pmapi.common.enumeration.ExportOptionEnum; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectLibFlagEnum; | |||||
import io.swagger.annotations.ApiModel; | import io.swagger.annotations.ApiModel; | ||||
import io.swagger.annotations.ApiModelProperty; | import io.swagger.annotations.ApiModelProperty; | ||||
import lombok.*; | import lombok.*; | ||||
import org.springframework.format.annotation.DateTimeFormat; | import org.springframework.format.annotation.DateTimeFormat; | ||||
import javax.validation.constraints.NotNull; | |||||
import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -91,7 +91,4 @@ public class ProjectListReq extends PagePo { | |||||
@ApiModelProperty("导出选项") | @ApiModelProperty("导出选项") | ||||
private List<ExportOptionEnum> exportOptionList; | private List<ExportOptionEnum> exportOptionList; | ||||
@ApiModelProperty(value = "表格类型",allowableValues = "0,1") | |||||
private Integer tableFlag; | |||||
} | } |
@@ -29,6 +29,9 @@ public class AnnualPlanListItemVO { | |||||
@ApiModelProperty("申报金额") | @ApiModelProperty("申报金额") | ||||
private BigDecimal declaredAmount; | private BigDecimal declaredAmount; | ||||
@ApiModelProperty("立项批复金额") | |||||
private BigDecimal approvalAmount; | |||||
@ApiModelProperty("预算年度") | @ApiModelProperty("预算年度") | ||||
private Integer projectYear; | private Integer projectYear; | ||||
@@ -322,6 +322,12 @@ public class ProjectDetailVO { | |||||
@ApiModelProperty("省级联审 审批结果") | @ApiModelProperty("省级联审 审批结果") | ||||
private String sjlsResult; | private String sjlsResult; | ||||
@ApiModelProperty("版本号") | |||||
private Integer version; | |||||
@ApiModelProperty("是否是最新版本") | |||||
private Boolean newest; | |||||
private LocalDateTime createOn; | private LocalDateTime createOn; | ||||
private LocalDateTime updateOn; | private LocalDateTime updateOn; | ||||
@@ -0,0 +1,92 @@ | |||||
package com.ningdatech.pmapi.projectlib.utils; | |||||
import cn.hutool.core.collection.CollUtil; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.ningdatech.basic.exception.BizException; | |||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.ningdatech.pmapi.common.constant.CommonConst; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import com.wflow.workflow.bean.vo.ProcessProgressVo; | |||||
import com.wflow.workflow.enums.ProcessHandlerEnum; | |||||
import com.wflow.workflow.enums.ProcessStatusEnum; | |||||
import com.wflow.workflow.service.ProcessInstanceService; | |||||
import liquibase.pro.packaged.I; | |||||
import lombok.RequiredArgsConstructor; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.stereotype.Component; | |||||
import java.util.Collection; | |||||
import java.util.Collections; | |||||
import java.util.List; | |||||
import java.util.Objects; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* 根据项目版本获取流程详情工具类 | |||||
* | |||||
* @author CMM | |||||
* @since 2023/04/20 09:57 | |||||
*/ | |||||
@Slf4j | |||||
@Component | |||||
@RequiredArgsConstructor | |||||
public class ProjectVersionUtil { | |||||
private final IProjectService projectService; | |||||
private final ProcessInstanceService processInstanceService; | |||||
private final IProjectInstService projectInstService; | |||||
/** | |||||
* 根据最新的项目ID获取临近项目版本的审核记录信息 | |||||
* @param projectId | |||||
* @return | |||||
*/ | |||||
public ProcessProgressVo getPreVerProcessInfo(Long projectId, InstTypeEnum instTypeEnum){ | |||||
Project project = projectService.getById(projectId); | |||||
if (Objects.isNull(project)){ | |||||
throw new BizException("当前项目不存在!"); | |||||
} | |||||
String projectCode = project.getProjectCode(); | |||||
if (StringUtils.isEmpty(projectCode)){ | |||||
throw new BizException("当前项目编号为空!"); | |||||
} | |||||
// 获取相同项目编号的项目 | |||||
List<Project> projectList = projectService.list(Wrappers.lambdaQuery(Project.class) | |||||
.eq(Project::getProjectCode, projectCode)); | |||||
if (projectList.size() < CommonConst.VERSION_SIZE){ | |||||
throw new BizException("未发现该项目的历史版本!"); | |||||
} | |||||
// 获取之前版本的项目 | |||||
int index = projectList.size() - 1; | |||||
ProcessProgressVo instanceDetail = null; | |||||
while (index > 0){ | |||||
index = index - 1; | |||||
Project preProject = projectList.get(index); | |||||
// 从项目流程实例关联表中查出实例详情 | |||||
List<ProjectInst> projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) | |||||
.eq(ProjectInst::getProjectId, preProject.getId()) | |||||
.eq(ProjectInst::getInstType,instTypeEnum.getCode())); | |||||
if (CollUtil.isNotEmpty(projectInstList)) { | |||||
List<ProcessProgressVo> processProgressVoList = projectInstList.stream() | |||||
.map(p -> processInstanceService.getProgressInstanceDetail(null, p.getInstCode())) | |||||
.collect(Collectors.toList()); | |||||
// 筛选出上个版本该类型审核流程通过的流程详情 | |||||
List<ProcessProgressVo> instanceDetailList = processProgressVoList.stream() | |||||
.filter(p -> ProcessStatusEnum.APPROVED.getDesc().equals(p.getStatus())) | |||||
.collect(Collectors.toList()); | |||||
if (CollUtil.isEmpty(instanceDetailList)){ | |||||
continue; | |||||
} | |||||
// 获取最后一个流程详情 | |||||
return instanceDetailList.get(instanceDetailList.size() - 1); | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -75,6 +75,11 @@ public class CheckProvincialReviewResultTask { | |||||
log.info("此项目 【{}】 还未审核",projectRes.getProjectId()); | log.info("此项目 【{}】 还未审核",projectRes.getProjectId()); | ||||
} else if(ProjectProvincialAuditStatusEnum.AUDITING.getCode().equals(projectRes.getProjectStatus())){ | } else if(ProjectProvincialAuditStatusEnum.AUDITING.getCode().equals(projectRes.getProjectStatus())){ | ||||
log.info("此项目 【{}】 还在审核中",projectRes.getProjectId()); | log.info("此项目 【{}】 还在审核中",projectRes.getProjectId()); | ||||
project.setUpdateOn(LocalDateTime.now()); | |||||
//保存审核结果 | |||||
project.setSjlsResult(CollUtil.isNotEmpty(projectRes.getProcessComment()) | |||||
? JSON.toJSONString(projectRes.getProcessComment()) : StringUtils.EMPTY); | |||||
projectService.updateById(project); | |||||
}else if(ProjectProvincialAuditStatusEnum.SUCCESS.getCode().equals(projectRes.getProjectStatus())){ | }else if(ProjectProvincialAuditStatusEnum.SUCCESS.getCode().equals(projectRes.getProjectStatus())){ | ||||
log.info("此项目 【{}】 审核通过",projectRes.getProjectId()); | log.info("此项目 【{}】 审核通过",projectRes.getProjectId()); | ||||
stateMachineUtils.pass(project); | stateMachineUtils.pass(project); | ||||
@@ -4,14 +4,9 @@ import java.net.InetAddress; | |||||
import java.net.UnknownHostException; | import java.net.UnknownHostException; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | |||||
import java.util.Objects; | |||||
import java.util.function.Function; | |||||
import com.ningdatech.basic.model.GenericResult; | import com.ningdatech.basic.model.GenericResult; | ||||
import com.ningdatech.pmapi.staging.model.entity.WorkNoticeStaging; | import com.ningdatech.pmapi.staging.model.entity.WorkNoticeStaging; | ||||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | ||||
import com.ningdatech.pmapi.staging.utils.WorkNoticeFlowMapUtil; | |||||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | ||||
import com.ningdatech.zwdd.client.ZwddClient; | import com.ningdatech.zwdd.client.ZwddClient; | ||||
import org.springframework.beans.BeanUtils; | import org.springframework.beans.BeanUtils; | ||||
@@ -20,13 +15,8 @@ import org.springframework.stereotype.Component; | |||||
import com.alibaba.fastjson.JSON; | import com.alibaba.fastjson.JSON; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import com.ningdatech.pmapi.scheduler.contants.TaskContant; | import com.ningdatech.pmapi.scheduler.contants.TaskContant; | ||||
import com.ningdatech.pmapi.staging.contants.StagingContant; | import com.ningdatech.pmapi.staging.contants.StagingContant; | ||||
import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; | |||||
import com.ningdatech.pmapi.staging.service.IProjectStagingService; | |||||
import com.ningdatech.pmapi.staging.utils.ProjectStatusFlowMapUtil; | |||||
import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
@@ -1,15 +1,15 @@ | |||||
package com.ningdatech.pmapi.staging.service; | package com.ningdatech.pmapi.staging.service; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.baomidou.mybatisplus.extension.service.IService; | |||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | ||||
import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; | |||||
import com.ningdatech.pmapi.staging.model.entity.WorkNoticeStaging; | import com.ningdatech.pmapi.staging.model.entity.WorkNoticeStaging; | ||||
import com.baomidou.mybatisplus.extension.service.IService; | |||||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | ||||
import java.util.List; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
* 服务类 | |||||
* 服务类 | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author CMM | * @author CMM | ||||
@@ -19,5 +19,14 @@ public interface INdWorkNoticeStagingService extends IService<WorkNoticeStaging> | |||||
Boolean addRetryTimes(WorkNoticeStaging workNoticeStaging); | Boolean addRetryTimes(WorkNoticeStaging workNoticeStaging); | ||||
public Boolean addByWorkNotice(WorkNoticeInfo workNoticeInfo, MsgTypeEnum msgType) ; | |||||
Boolean addByWorkNotice(WorkNoticeInfo workNoticeInfo, MsgTypeEnum msgType); | |||||
/** | |||||
* 批量保存工作通知 | |||||
* | |||||
* @param workNoticeInfos 工作通知内容 | |||||
* @param msgType 通知类型 | |||||
*/ | |||||
void addByWorkNotice(List<WorkNoticeInfo> workNoticeInfos, MsgTypeEnum msgType); | |||||
} | } |
@@ -13,10 +13,12 @@ import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.List; | |||||
import java.util.stream.Collectors; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
* 服务实现类 | |||||
* 服务实现类 | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author CMM | * @author CMM | ||||
@@ -33,6 +35,7 @@ public class NdWorkNoticeStagingServiceImpl extends ServiceImpl<NdWorkNoticeStag | |||||
/** | /** | ||||
* 增加 重试次数 和下次扫描时间 | * 增加 重试次数 和下次扫描时间 | ||||
* | |||||
* @param workNoticeStaging | * @param workNoticeStaging | ||||
* @return java.lang.Boolean | * @return java.lang.Boolean | ||||
* @author CMM | * @author CMM | ||||
@@ -41,22 +44,23 @@ public class NdWorkNoticeStagingServiceImpl extends ServiceImpl<NdWorkNoticeStag | |||||
@Override | @Override | ||||
public Boolean addRetryTimes(WorkNoticeStaging workNoticeStaging) { | public Boolean addRetryTimes(WorkNoticeStaging workNoticeStaging) { | ||||
Integer retryTimes = workNoticeStaging.getRetryTimes() + 1; | Integer retryTimes = workNoticeStaging.getRetryTimes() + 1; | ||||
if(!workNoticeFlowMapUtil.intervalTimeMap.containsKey(retryTimes)){ | |||||
if (!workNoticeFlowMapUtil.intervalTimeMap.containsKey(retryTimes)) { | |||||
log.info("没有对应重试间隔时间 添加重试信息失败"); | log.info("没有对应重试间隔时间 添加重试信息失败"); | ||||
return Boolean.FALSE; | return Boolean.FALSE; | ||||
} | } | ||||
Integer addSeconds = workNoticeFlowMapUtil.intervalTimeMap.get(retryTimes); | Integer addSeconds = workNoticeFlowMapUtil.intervalTimeMap.get(retryTimes); | ||||
Boolean dead = Boolean.FALSE; | Boolean dead = Boolean.FALSE; | ||||
//超过重试最大次数 dead置为 true | //超过重试最大次数 dead置为 true | ||||
if(retryTimes.compareTo(StagingContant.Retry.MAX_RETRY_TIMES) > 0){ | |||||
if (retryTimes.compareTo(StagingContant.Retry.MAX_RETRY_TIMES) > 0) { | |||||
dead = Boolean.TRUE; | dead = Boolean.TRUE; | ||||
} | } | ||||
LocalDateTime nextRetryTime = LocalDateTime.now().plusSeconds(addSeconds); | LocalDateTime nextRetryTime = LocalDateTime.now().plusSeconds(addSeconds); | ||||
return mapper.addRetryTimes(workNoticeStaging.getId(),retryTimes,nextRetryTime,dead); | |||||
return mapper.addRetryTimes(workNoticeStaging.getId(), retryTimes, nextRetryTime, dead); | |||||
} | } | ||||
/** | /** | ||||
* 在对应的流程处理后,增加一个工作通知到暂存表中 | * 在对应的流程处理后,增加一个工作通知到暂存表中 | ||||
* | |||||
* @param workNoticeInfo | * @param workNoticeInfo | ||||
* @param msgType | * @param msgType | ||||
* @return java.lang.Boolean | * @return java.lang.Boolean | ||||
@@ -80,4 +84,34 @@ public class NdWorkNoticeStagingServiceImpl extends ServiceImpl<NdWorkNoticeStag | |||||
.build(); | .build(); | ||||
return this.save(workNoticeStaging); | return this.save(workNoticeStaging); | ||||
} | } | ||||
/** | |||||
* 在对应的流程处理后,增加一个工作通知到暂存表中 | |||||
* | |||||
* @param workNoticeInfo | |||||
* @param msgType | |||||
* @return java.lang.Boolean | |||||
* @author CMM | |||||
* @since 2023/02/28 20:02 | |||||
*/ | |||||
@Override | |||||
public void addByWorkNotice(List<WorkNoticeInfo> workNoticeInfos, MsgTypeEnum msgType) { | |||||
LocalDateTime now = LocalDateTime.now(); | |||||
List<WorkNoticeStaging> workNoticeInfoList = workNoticeInfos.stream() | |||||
.map(workNoticeInfo -> WorkNoticeStaging.builder() | |||||
.accountId(workNoticeInfo.getAccountId()) | |||||
.msg(workNoticeInfo.getMsg()) | |||||
.bizMsgId(workNoticeInfo.getBizMsgId()) | |||||
.organizationCode(workNoticeInfo.getOrganizationCode()) | |||||
.organizationName(workNoticeInfo.getOrganizationName()) | |||||
.receiverUserId(workNoticeInfo.getReceiverUserId()) | |||||
.msgType(msgType) | |||||
.createOn(now) | |||||
.updateOn(now) | |||||
.nextTime(now) | |||||
.retryTimes(0) | |||||
.build()).collect(Collectors.toList()); | |||||
saveBatch(workNoticeInfoList); | |||||
} | |||||
} | } |
@@ -6,7 +6,7 @@ import com.ningdatech.pmapi.staging.contants.StagingContant; | |||||
import com.ningdatech.pmapi.staging.mapper.ProjectStagingMapper; | import com.ningdatech.pmapi.staging.mapper.ProjectStagingMapper; | ||||
import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; | import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; | ||||
import com.ningdatech.pmapi.staging.service.IProjectStagingService; | import com.ningdatech.pmapi.staging.service.IProjectStagingService; | ||||
import com.ningdatech.pmapi.staging.utils.ProjectStatusFlowMapUtil; | |||||
import com.ningdatech.pmapi.staging.utils.ProjectStatusFlowUtil; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
@@ -28,7 +28,7 @@ public class ProjectStagingServiceImpl extends ServiceImpl<ProjectStagingMapper, | |||||
private final ProjectStagingMapper mapper; | private final ProjectStagingMapper mapper; | ||||
private final ProjectStatusFlowMapUtil projectStatusFlowMapUtil; | |||||
private final ProjectStatusFlowUtil projectStatusFlowUtil; | |||||
/** | /** | ||||
* 在某些状态节点 增加一个项目到状态暂存库 | * 在某些状态节点 增加一个项目到状态暂存库 | ||||
@@ -61,11 +61,11 @@ public class ProjectStagingServiceImpl extends ServiceImpl<ProjectStagingMapper, | |||||
@Override | @Override | ||||
public Boolean addRetryTimes(ProjectStaging projectStaging) { | public Boolean addRetryTimes(ProjectStaging projectStaging) { | ||||
Integer retryTimes = projectStaging.getRetryTimes() + 1; | Integer retryTimes = projectStaging.getRetryTimes() + 1; | ||||
if(!projectStatusFlowMapUtil.intervalTimeMap.containsKey(retryTimes)){ | |||||
if(!projectStatusFlowUtil.intervalTimeMap.containsKey(retryTimes)){ | |||||
log.info("没有对应重试间隔时间 添加重试信息失败"); | log.info("没有对应重试间隔时间 添加重试信息失败"); | ||||
return Boolean.FALSE; | return Boolean.FALSE; | ||||
} | } | ||||
Integer addSeconds = projectStatusFlowMapUtil.intervalTimeMap.get(retryTimes); | |||||
Integer addSeconds = projectStatusFlowUtil.intervalTimeMap.get(retryTimes); | |||||
Boolean dead = Boolean.FALSE; | Boolean dead = Boolean.FALSE; | ||||
//超过重试最大次数 dead置为 true | //超过重试最大次数 dead置为 true | ||||
if(retryTimes.compareTo(StagingContant.Retry.MAX_RETRY_TIMES) > 0){ | if(retryTimes.compareTo(StagingContant.Retry.MAX_RETRY_TIMES) > 0){ | ||||
@@ -29,10 +29,6 @@ public class ProjectStatusFlowMapUtil { | |||||
private ReviewByDeptJointManage reviewByDeptJointManage; | private ReviewByDeptJointManage reviewByDeptJointManage; | ||||
public Map<Integer, Function<Project,Boolean>> statusFlowFunctionMap = Maps.newHashMap(); | public Map<Integer, Function<Project,Boolean>> statusFlowFunctionMap = Maps.newHashMap(); | ||||
/** | |||||
* key 重试的次数 , value 是增加是描述 | |||||
*/ | |||||
public Map<Integer, Integer> intervalTimeMap = Maps.newHashMap(); | |||||
/** | /** | ||||
* 初始化业务分派逻辑,代替了if-else部分 | * 初始化业务分派逻辑,代替了if-else部分 | ||||
@@ -47,22 +43,4 @@ public class ProjectStatusFlowMapUtil { | |||||
statusFlowFunctionMap.put(ProjectStatusEnum.DEPARTMENT_JOINT_REVIEW.getCode(), | statusFlowFunctionMap.put(ProjectStatusEnum.DEPARTMENT_JOINT_REVIEW.getCode(), | ||||
project->reviewByDeptJointManage.startTheProcess(project)); | project->reviewByDeptJointManage.startTheProcess(project)); | ||||
} | } | ||||
/** | |||||
* 扫描的间隔越来越长 秒数 | |||||
*/ | |||||
@PostConstruct | |||||
public void intervalTimeMapInit(){ | |||||
intervalTimeMap.put(1,60 * 2); | |||||
intervalTimeMap.put(2,60 * 6); | |||||
intervalTimeMap.put(3,60 * 15); | |||||
intervalTimeMap.put(4,60 * 30); | |||||
intervalTimeMap.put(5,60 * 60); | |||||
intervalTimeMap.put(6,60 * 60 * 2); | |||||
intervalTimeMap.put(7,60 * 60 * 5); | |||||
intervalTimeMap.put(8,60 * 60 * 12); | |||||
intervalTimeMap.put(9,60 * 60 * 24); | |||||
intervalTimeMap.put(10,60 * 60 * 72); | |||||
} | |||||
} | } |
@@ -0,0 +1,45 @@ | |||||
package com.ningdatech.pmapi.staging.utils; | |||||
import com.google.common.collect.Maps; | |||||
import com.ningdatech.pmapi.projectdeclared.manage.ReviewByDeptJointManage; | |||||
import com.ningdatech.pmapi.projectdeclared.manage.ReviewByProvincialDeptManage; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Component; | |||||
import javax.annotation.PostConstruct; | |||||
import java.util.Map; | |||||
import java.util.function.Function; | |||||
/** | |||||
* @Classname ProjectStatusFlowMapUtil | |||||
* @Description 状态流转 事件函数MAP | |||||
* @Date 2023/2/15 11:19 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@Component | |||||
public class ProjectStatusFlowUtil { | |||||
/** | |||||
* key 重试的次数 , value 是增加是描述 | |||||
*/ | |||||
public Map<Integer, Integer> intervalTimeMap = Maps.newHashMap(); | |||||
/** | |||||
* 初始化业务分派逻辑,代替了if-else部分 | |||||
* key: 枚举 状态值 | |||||
* value: lambda表达式,最终会获取发起实例的函数 | |||||
*/ | |||||
public ProjectStatusFlowUtil(){ | |||||
intervalTimeMap.put(1,60 * 2); | |||||
intervalTimeMap.put(2,60 * 6); | |||||
intervalTimeMap.put(3,60 * 15); | |||||
intervalTimeMap.put(4,60 * 30); | |||||
intervalTimeMap.put(5,60 * 60); | |||||
intervalTimeMap.put(6,60 * 60 * 2); | |||||
intervalTimeMap.put(7,60 * 60 * 5); | |||||
intervalTimeMap.put(8,60 * 60 * 12); | |||||
intervalTimeMap.put(9,60 * 60 * 24); | |||||
intervalTimeMap.put(10,60 * 60 * 72); | |||||
} | |||||
} |
@@ -2,6 +2,8 @@ package com.ningdatech.pmapi.staging.utils; | |||||
import java.util.Map; | import java.util.Map; | ||||
import javax.annotation.PostConstruct; | import javax.annotation.PostConstruct; | ||||
import lombok.AllArgsConstructor; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import com.google.common.collect.Maps; | import com.google.common.collect.Maps; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
@@ -13,7 +15,7 @@ import lombok.RequiredArgsConstructor; | |||||
* @since 2023/02/28 17:03 | * @since 2023/02/28 17:03 | ||||
*/ | */ | ||||
@Component | @Component | ||||
@RequiredArgsConstructor | |||||
@AllArgsConstructor | |||||
public class WorkNoticeFlowMapUtil { | public class WorkNoticeFlowMapUtil { | ||||
/** | /** | ||||
* key 重试的次数 , value 是增加是描述 | * key 重试的次数 , value 是增加是描述 | ||||
@@ -23,8 +25,7 @@ public class WorkNoticeFlowMapUtil { | |||||
/** | /** | ||||
* 扫描的间隔越来越长 秒数 | * 扫描的间隔越来越长 秒数 | ||||
*/ | */ | ||||
@PostConstruct | |||||
public void intervalTimeMapInit(){ | |||||
public WorkNoticeFlowMapUtil(){ | |||||
intervalTimeMap.put(1,60 * 2); | intervalTimeMap.put(1,60 * 2); | ||||
intervalTimeMap.put(2,60 * 6); | intervalTimeMap.put(2,60 * 6); | ||||
intervalTimeMap.put(3,60 * 15); | intervalTimeMap.put(3,60 * 15); | ||||
@@ -2,32 +2,56 @@ package com.ningdatech.pmapi.sys.manage; | |||||
import cn.hutool.core.bean.BeanUtil; | import cn.hutool.core.bean.BeanUtil; | ||||
import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||
import com.alibaba.fastjson.JSON; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 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.IdVo; | ||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
import com.ningdatech.basic.util.CollUtils; | import com.ningdatech.basic.util.CollUtils; | ||||
import com.ningdatech.file.entity.vo.result.AttachFileVo; | import com.ningdatech.file.entity.vo.result.AttachFileVo; | ||||
import com.ningdatech.file.service.FileService; | import com.ningdatech.file.service.FileService; | ||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | |||||
import com.ningdatech.pmapi.common.util.BizUtils; | import com.ningdatech.pmapi.common.util.BizUtils; | ||||
import com.ningdatech.pmapi.organization.model.entity.DingEmployeeInfo; | |||||
import com.ningdatech.pmapi.organization.model.entity.DingOrganization; | |||||
import com.ningdatech.pmapi.organization.service.IDingEmployeeInfoService; | |||||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | |||||
import com.ningdatech.pmapi.sys.enumeration.NoticeTypeEnum; | import com.ningdatech.pmapi.sys.enumeration.NoticeTypeEnum; | ||||
import com.ningdatech.pmapi.sys.model.entity.Notice; | import com.ningdatech.pmapi.sys.model.entity.Notice; | ||||
import com.ningdatech.pmapi.sys.model.entity.Notify; | |||||
import com.ningdatech.pmapi.sys.model.req.NoticeListReq; | import com.ningdatech.pmapi.sys.model.req.NoticeListReq; | ||||
import com.ningdatech.pmapi.sys.model.req.NoticeSaveReq; | import com.ningdatech.pmapi.sys.model.req.NoticeSaveReq; | ||||
import com.ningdatech.pmapi.sys.model.req.NoticeStatusModifyReq; | import com.ningdatech.pmapi.sys.model.req.NoticeStatusModifyReq; | ||||
import com.ningdatech.pmapi.sys.model.vo.NoticeDetailVO; | import com.ningdatech.pmapi.sys.model.vo.NoticeDetailVO; | ||||
import com.ningdatech.pmapi.sys.model.vo.NoticeListItemVO; | import com.ningdatech.pmapi.sys.model.vo.NoticeListItemVO; | ||||
import com.ningdatech.pmapi.sys.service.INoticeService; | import com.ningdatech.pmapi.sys.service.INoticeService; | ||||
import com.ningdatech.pmapi.sys.service.INotifyService; | |||||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | |||||
import com.ningdatech.pmapi.todocenter.model.dto.ProjectAuditMsgExtraDTO; | |||||
import com.ningdatech.pmapi.user.entity.UserInfo; | |||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||||
import com.ningdatech.pmapi.user.service.IUserInfoService; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.flowable.engine.RuntimeService; | |||||
import org.flowable.engine.runtime.ActivityInstance; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Objects; | |||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
import static com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant.AUDIT_WORK_TITLE; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
* MsgManage | * MsgManage | ||||
@@ -38,11 +62,26 @@ import java.util.stream.Collectors; | |||||
*/ | */ | ||||
@Component | @Component | ||||
@RequiredArgsConstructor | @RequiredArgsConstructor | ||||
@Slf4j | |||||
public class NoticeManage { | public class NoticeManage { | ||||
private final INoticeService noticeService; | private final INoticeService noticeService; | ||||
private final FileService fileService; | private final FileService fileService; | ||||
private final IUserInfoService userInfoService; | |||||
private final IDingEmployeeInfoService dingEmployeeInfoService; | |||||
private final IDingOrganizationService dingOrganizationService; | |||||
private final INotifyService notifyService; | |||||
private final INdWorkNoticeStagingService workNoticeStagingService; | |||||
private final RuntimeService runtimeService; | |||||
private final UserInfoHelper userInfoHelper; | |||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public IdVo<Long> saveOrModify(NoticeSaveReq req) { | public IdVo<Long> saveOrModify(NoticeSaveReq req) { | ||||
Notice notice = BeanUtil.copyProperties(req, Notice.class); | Notice notice = BeanUtil.copyProperties(req, Notice.class); | ||||
@@ -128,4 +167,117 @@ public class NoticeManage { | |||||
noticeService.removeById(id); | noticeService.removeById(id); | ||||
} | } | ||||
/** | |||||
* 发送消息 | |||||
* @param employeeCode 员工号 | |||||
* @param userId 用户ID | |||||
* @param project 项目 | |||||
* @param procDefinitionName 流程定义名 | |||||
* @param template 消息模板内容 | |||||
* @param msgTypeEnum 枚举 | |||||
*/ | |||||
public void sendNotice(String employeeCode, Long userId, Project project, String procDefinitionName, | |||||
String template, MsgTypeEnum msgTypeEnum){ | |||||
// 获取发送浙政钉工作通知必要信息 | |||||
WorkNoticeInfo passWorkNoticeInfo = getSendWorkNoticeInfo(employeeCode); | |||||
String passMsg = String.format(template, project.getProjectName(), procDefinitionName); | |||||
passWorkNoticeInfo.setMsg(passMsg); | |||||
// 放入系统通知表中,保存记录 | |||||
Notify notify = assemblyAuditNotify(userId, project, passMsg); | |||||
notify.setType(msgTypeEnum.name()); | |||||
notifyService.save(notify); | |||||
// 放入工作通知暂存表中,通过扫表异步发送 | |||||
workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo, msgTypeEnum); | |||||
} | |||||
/** | |||||
* 获取发送浙政钉工作通知的信息 | |||||
* | |||||
* @param currentEmployeeCode | |||||
* @return com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo | |||||
* @author CMM | |||||
* @since 2023/02/15 14:04 | |||||
*/ | |||||
public WorkNoticeInfo getSendWorkNoticeInfo(String currentEmployeeCode) { | |||||
UserInfo auditUserInfo = userInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getEmployeeCode,currentEmployeeCode).last("limit 1")); | |||||
if (Objects.isNull(auditUserInfo)) { | |||||
throw new BizException("该用户不存在!"); | |||||
} | |||||
WorkNoticeInfo workNoticeInfo = new WorkNoticeInfo(); | |||||
Long accountId = auditUserInfo.getAccountId(); | |||||
if (Objects.isNull(accountId)) { | |||||
throw new BizException("该用户没有录入浙政钉信息!"); | |||||
} | |||||
workNoticeInfo.setAccountId(accountId); | |||||
// 根据浙政钉用户ID获取部门code | |||||
DingEmployeeInfo employeeInfo = dingEmployeeInfoService.getOne(Wrappers.lambdaQuery(DingEmployeeInfo.class) | |||||
.eq(DingEmployeeInfo::getAccountId, accountId) | |||||
.eq(DingEmployeeInfo::getMainJob,String.valueOf(Boolean.TRUE)) | |||||
.last("limit 1")); | |||||
String organizationCode = employeeInfo.getOrganizationCode(); | |||||
workNoticeInfo.setOrganizationCode(organizationCode); | |||||
// 根据部门code获取部门名称 | |||||
DingOrganization dingOrganization = dingOrganizationService.getOne(Wrappers.lambdaQuery(DingOrganization.class) | |||||
.eq(DingOrganization::getOrganizationCode, organizationCode)); | |||||
String organizationName = dingOrganization.getOrganizationName(); | |||||
workNoticeInfo.setOrganizationName(organizationName); | |||||
// 构建唯一的消息ID | |||||
String bizMsgId = "ZD_WORK_NOTICE_" + StrUtil.UNDERLINE + organizationCode + StrUtil.UNDERLINE | |||||
+ organizationName + accountId + StrUtil.UNDERLINE + System.currentTimeMillis(); | |||||
workNoticeInfo.setBizMsgId(bizMsgId); | |||||
String receiverUserId = String.valueOf(accountId); | |||||
workNoticeInfo.setReceiverUserId(receiverUserId); | |||||
return workNoticeInfo; | |||||
} | |||||
/** | |||||
* 装配项目审核工作通知 | |||||
* @param userId | |||||
* @param project | |||||
* @param msg | |||||
*/ | |||||
private Notify assemblyAuditNotify(Long userId, Project project, String msg) { | |||||
Notify notify = new Notify(); | |||||
notify.setTitle(AUDIT_WORK_TITLE); | |||||
notify.setUserId(userId); | |||||
notify.setContent(msg); | |||||
notify.setReaded(Boolean.FALSE); | |||||
notify.setCreateTime(LocalDateTime.now()); | |||||
ProjectAuditMsgExtraDTO msgExtraDto = new ProjectAuditMsgExtraDTO(); | |||||
msgExtraDto.setProjectId(project.getId()); | |||||
msgExtraDto.setInstanceId(project.getInstCode()); | |||||
String extraJson = JSON.toJSONString(msgExtraDto); | |||||
notify.setExtraInfo(extraJson); | |||||
return notify; | |||||
} | |||||
/** | |||||
* 找寻第一个审核人 去发消息 | |||||
* @param project | |||||
* @param formName | |||||
* @param template | |||||
* @param msgTypeEnum | |||||
*/ | |||||
public void sendFirtUser(Project project, String formName,String instanceId, String template, MsgTypeEnum msgTypeEnum) { | |||||
try { | |||||
List<ActivityInstance> activityInstances = runtimeService.createActivityInstanceQuery() | |||||
.processInstanceId(instanceId) | |||||
.activityType("userTask") | |||||
.orderByActivityInstanceStartTime() | |||||
.asc() | |||||
.list(); | |||||
for (ActivityInstance activityInstance : activityInstances) { | |||||
if(StringUtils.isNotBlank(activityInstance.getAssignee())){ | |||||
UserFullInfoDTO user = userInfoHelper.getUserFullInfoByEmployeeCode(activityInstance.getAssignee()); | |||||
sendNotice(activityInstance.getAssignee(), user.getUserId(), project, formName, | |||||
template, msgTypeEnum); | |||||
} | |||||
} | |||||
}catch (Exception e){ | |||||
log.error("发送消息失败 :" + e); | |||||
} | |||||
} | |||||
} | } |
@@ -45,14 +45,14 @@ public class NotifyManage { | |||||
.like(Objects.nonNull(notifyListReq.getTitle()), Notify::getTitle, notifyListReq.getTitle()) | .like(Objects.nonNull(notifyListReq.getTitle()), Notify::getTitle, notifyListReq.getTitle()) | ||||
.eq(Objects.nonNull(notifyListReq.getType()), Notify::getType, notifyListReq.getType()) | .eq(Objects.nonNull(notifyListReq.getType()), Notify::getType, notifyListReq.getType()) | ||||
.orderByDesc(Notify::getCreateTime); | .orderByDesc(Notify::getCreateTime); | ||||
notifyService.page(page,wrapper); | |||||
if(page.getTotal() == 0L){ | |||||
notifyService.page(page, wrapper); | |||||
if (page.getTotal() == 0L) { | |||||
return PageVo.empty(); | return PageVo.empty(); | ||||
} | } | ||||
List<NotifyVO> list = page.getRecords().stream() | List<NotifyVO> list = page.getRecords().stream() | ||||
.map(n -> { | .map(n -> { | ||||
NotifyVO notifyVo = new NotifyVO(); | NotifyVO notifyVo = new NotifyVO(); | ||||
BeanUtil.copyProperties(n,notifyVo); | |||||
BeanUtil.copyProperties(n, notifyVo); | |||||
String extraInfo = n.getExtraInfo(); | String extraInfo = n.getExtraInfo(); | ||||
if (StringUtils.isNotBlank(extraInfo)) { | if (StringUtils.isNotBlank(extraInfo)) { | ||||
JSONObject jsonObject = JSON.parseObject(extraInfo); | JSONObject jsonObject = JSON.parseObject(extraInfo); | ||||
@@ -66,12 +66,12 @@ public class NotifyManage { | |||||
return notifyVo; | return notifyVo; | ||||
}) | }) | ||||
.collect(Collectors.toList()); | .collect(Collectors.toList()); | ||||
return PageVo.of(list,page.getTotal()); | |||||
return PageVo.of(list, page.getTotal()); | |||||
} | } | ||||
public NotifyVO detail(Long id) { | public NotifyVO detail(Long id) { | ||||
Notify one = notifyService.getById(id); | Notify one = notifyService.getById(id); | ||||
return BeanUtil.copyProperties(one,NotifyVO.class); | |||||
return BeanUtil.copyProperties(one, NotifyVO.class); | |||||
} | } | ||||
public Boolean read(Long id) { | public Boolean read(Long id) { | ||||
@@ -1,22 +1,32 @@ | |||||
package com.ningdatech.pmapi.todocenter.manage; | package com.ningdatech.pmapi.todocenter.manage; | ||||
import cn.hutool.core.collection.CollUtil; | |||||
import cn.hutool.core.util.StrUtil; | |||||
import static com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant.*; | |||||
import java.time.LocalDateTime; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Objects; | |||||
import java.util.Optional; | |||||
import java.util.stream.Collectors; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.flowable.engine.HistoryService; | |||||
import org.flowable.engine.RuntimeService; | |||||
import org.flowable.engine.TaskService; | |||||
import org.flowable.engine.history.HistoricProcessInstance; | |||||
import org.flowable.engine.task.Comment; | |||||
import org.flowable.variable.api.history.HistoricVariableInstance; | |||||
import org.springframework.beans.BeanUtils; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
import com.alibaba.fastjson.JSON; | import com.alibaba.fastjson.JSON; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.file.service.FileService; | |||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | |||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | ||||
import com.ningdatech.pmapi.organization.model.entity.DingEmployeeInfo; | |||||
import com.ningdatech.pmapi.organization.model.entity.DingOrganization; | |||||
import com.ningdatech.pmapi.organization.service.IDingEmployeeInfoService; | |||||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||||
import com.ningdatech.pmapi.projectdeclared.manage.DeclaredProjectManage; | import com.ningdatech.pmapi.projectdeclared.manage.DeclaredProjectManage; | ||||
import com.ningdatech.pmapi.projectdeclared.manage.DefaultDeclaredProjectManage; | |||||
import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectDraftSaveDTO; | import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectDraftSaveDTO; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | |||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectApplicationDTO; | import com.ningdatech.pmapi.projectlib.model.dto.ProjectApplicationDTO; | ||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
@@ -25,47 +35,21 @@ import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.signature.service.ICompanySignatureService; | |||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | ||||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | |||||
import com.ningdatech.pmapi.staging.service.IProjectStagingService; | import com.ningdatech.pmapi.staging.service.IProjectStagingService; | ||||
import com.ningdatech.pmapi.sys.model.entity.Notify; | |||||
import com.ningdatech.pmapi.sys.service.INotifyService; | |||||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | |||||
import com.ningdatech.pmapi.sys.manage.NoticeManage; | |||||
import com.ningdatech.pmapi.todocenter.constant.TodoCenterContant; | import com.ningdatech.pmapi.todocenter.constant.TodoCenterContant; | ||||
import com.ningdatech.pmapi.todocenter.model.dto.ProjectAuditMsgExtraDTO; | |||||
import com.ningdatech.pmapi.todocenter.service.StatisticsService; | |||||
import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils; | |||||
import com.ningdatech.pmapi.todocenter.utils.PdfUtils; | |||||
import com.ningdatech.pmapi.user.entity.UserInfo; | |||||
import com.ningdatech.pmapi.user.service.IUserInfoService; | |||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import com.wflow.contants.HisProInsEndActId; | import com.wflow.contants.HisProInsEndActId; | ||||
import com.wflow.contants.WflowContant; | |||||
import com.wflow.workflow.bean.process.ProgressNode; | import com.wflow.workflow.bean.process.ProgressNode; | ||||
import com.wflow.workflow.bean.process.enums.NodeTypeEnum; | import com.wflow.workflow.bean.process.enums.NodeTypeEnum; | ||||
import com.wflow.workflow.bean.vo.ProcessProgressVo; | import com.wflow.workflow.bean.vo.ProcessProgressVo; | ||||
import com.wflow.workflow.enums.ProcessHandlerEnum; | import com.wflow.workflow.enums.ProcessHandlerEnum; | ||||
import com.wflow.workflow.service.ProcessInstanceService; | import com.wflow.workflow.service.ProcessInstanceService; | ||||
import com.wflow.workflow.service.ProcessTaskService; | |||||
import cn.hutool.core.collection.CollUtil; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.flowable.engine.HistoryService; | |||||
import org.flowable.engine.RuntimeService; | |||||
import org.flowable.engine.TaskService; | |||||
import org.flowable.engine.history.HistoricProcessInstance; | |||||
import org.flowable.engine.task.Comment; | |||||
import org.flowable.variable.api.history.HistoricVariableInstance; | |||||
import org.springframework.beans.BeanUtils; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
import java.time.LocalDateTime; | |||||
import java.util.*; | |||||
import java.util.stream.Collectors; | |||||
import static com.ningdatech.pmapi.todocenter.constant.WorkNoticeContant.*; | |||||
/** | /** | ||||
* @Classname HandlerManage | * @Classname HandlerManage | ||||
@@ -82,17 +66,13 @@ public class HandlerManage { | |||||
private final TaskService taskService; | private final TaskService taskService; | ||||
private final HistoryService historyService; | private final HistoryService historyService; | ||||
private final IUserInfoService userInfoService; | |||||
private final IProjectService projectService; | private final IProjectService projectService; | ||||
private final StateMachineUtils stateMachineUtils; | private final StateMachineUtils stateMachineUtils; | ||||
private final IDingEmployeeInfoService dingEmployeeInfoService; | |||||
private final IDingOrganizationService dingOrganizationService; | |||||
private final ProcessInstanceService processInstanceService; | private final ProcessInstanceService processInstanceService; | ||||
private final INdWorkNoticeStagingService workNoticeStagingService; | |||||
private final IProjectApplicationService projectApplicationService; | private final IProjectApplicationService projectApplicationService; | ||||
private final IProjectStagingService projectStagingService; | private final IProjectStagingService projectStagingService; | ||||
private final IProjectInstService projectInstService; | private final IProjectInstService projectInstService; | ||||
private final INotifyService notifyService; | |||||
private final NoticeManage noticeManage; | |||||
private final DeclaredProjectManage declaredProjectManage; | private final DeclaredProjectManage declaredProjectManage; | ||||
/** | /** | ||||
@@ -147,16 +127,9 @@ public class HandlerManage { | |||||
default: | default: | ||||
throw new IllegalStateException("Unexpected value: " + declaredProject.getStatus()); | throw new IllegalStateException("Unexpected value: " + declaredProject.getStatus()); | ||||
} | } | ||||
// 获取发送浙政钉工作通知必要信息 | |||||
WorkNoticeInfo passWorkNoticeInfo2 = getSendWorkNoticeInfo(currentEmployeeCode); | |||||
String passMsg2 = String.format(PASS_MSG_TEMPLATE2, declaredProject.getProjectName(), instance.getProcessDefinitionName()); | |||||
passWorkNoticeInfo2.setMsg(passMsg2); | |||||
// 放入系统通知表中,保存记录 | |||||
Notify notify = assemblyAuditNotify(userId, declaredProject, passMsg2); | |||||
notify.setType(MsgTypeEnum.PROJECT_REVIEW_PASS.name()); | |||||
notifyService.save(notify); | |||||
// 放入工作通知暂存表中,通过扫表异步发送 | |||||
workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo2, MsgTypeEnum.PROJECT_REVIEW_PASS); | |||||
//发送消息 | |||||
noticeManage.sendNotice(instance.getStartUserId(),userId,declaredProject,instance.getProcessDefinitionName(), | |||||
PASS_MSG_TEMPLATE2,MsgTypeEnum.PROJECT_REVIEW_PASS); | |||||
} else { | } else { | ||||
// 若有下一个审核人(当前节点的用户), | // 若有下一个审核人(当前节点的用户), | ||||
// 向其发送浙政钉工作通知:标题:审核任务 内容:【单位名称】的【项目名称】需要您审核。 | // 向其发送浙政钉工作通知:标题:审核任务 内容:【单位名称】的【项目名称】需要您审核。 | ||||
@@ -164,18 +137,13 @@ public class HandlerManage { | |||||
if (Objects.isNull(currentEmployeeCode)) { | if (Objects.isNull(currentEmployeeCode)) { | ||||
throw new BizException("审核人信息不存在!"); | throw new BizException("审核人信息不存在!"); | ||||
} | } | ||||
WorkNoticeInfo sendWorkNoticeInfo = getSendWorkNoticeInfo(currentEmployeeCode); | |||||
String msg = String.format(PASS_MSG_TEMPLATE, sendWorkNoticeInfo.getOrganizationName(), declaredProject.getProjectName()); | |||||
sendWorkNoticeInfo.setMsg(msg); | |||||
// 放入系统通知表中,保存记录 | |||||
Notify notify = assemblyAuditNotify(userId, declaredProject, msg); | |||||
notify.setType(MsgTypeEnum.PROJECT_REVIEW.name()); | |||||
notifyService.save(notify); | |||||
// 放入工作通知暂存表中,通过扫表异步发送 | |||||
workNoticeStagingService.addByWorkNotice(sendWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW); | |||||
//发送消息 | |||||
noticeManage.sendNotice(currentEmployeeCode,userId,declaredProject,instance.getProcessDefinitionName(), | |||||
PASS_MSG_TEMPLATE,MsgTypeEnum.PROJECT_REVIEW); | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* 驳回后 所处理的逻辑 | * 驳回后 所处理的逻辑 | ||||
* @param declaredProject | * @param declaredProject | ||||
@@ -185,17 +153,9 @@ public class HandlerManage { | |||||
Long userId = LoginUserUtil.getUserId(); | Long userId = LoginUserUtil.getUserId(); | ||||
// 更新项目状态和流程状态 | // 更新项目状态和流程状态 | ||||
updateRejectProjectStatus(userId, declaredProject); | updateRejectProjectStatus(userId, declaredProject); | ||||
// 获取发送浙政钉工作通知必要信息 | |||||
WorkNoticeInfo rejectWorkNoticeInfo = getSendWorkNoticeInfo(instance.getStartUserId()); | |||||
String rejectMsg = String.format(REJECT_MSG_TEMPLATE, declaredProject.getProjectName(), | |||||
instance.getProcessDefinitionName()); | |||||
rejectWorkNoticeInfo.setMsg(rejectMsg); | |||||
// 放入系统通知表中,保存记录 | |||||
Notify notify = assemblyAuditNotify(userId, declaredProject, rejectMsg); | |||||
notify.setType(MsgTypeEnum.PROJECT_REVIEW_REJECT.name()); | |||||
notifyService.save(notify); | |||||
// 放入工作通知暂存表中,通过扫表异步发送 | |||||
workNoticeStagingService.addByWorkNotice(rejectWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW_REJECT); | |||||
//发送消息 | |||||
noticeManage.sendNotice(instance.getStartUserId(),userId,declaredProject,instance.getProcessDefinitionName(), | |||||
REJECT_MSG_TEMPLATE,MsgTypeEnum.PROJECT_REVIEW_REJECT); | |||||
} | } | ||||
/** | /** | ||||
@@ -269,17 +229,9 @@ public class HandlerManage { | |||||
public void afterBackTodo(Project declaredProject, HistoricProcessInstance instance) { | public void afterBackTodo(Project declaredProject, HistoricProcessInstance instance) { | ||||
Long userId = LoginUserUtil.getUserId(); | Long userId = LoginUserUtil.getUserId(); | ||||
// 给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被退回,请及时处理。 | // 给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被退回,请及时处理。 | ||||
// 获取发送浙政钉工作通知必要信息 | |||||
WorkNoticeInfo backWorkNoticeInfo = getSendWorkNoticeInfo(instance.getStartUserId()); | |||||
String backMsg = String.format(BACK_MSG_TEMPLATE, declaredProject.getProjectName(), | |||||
instance.getProcessDefinitionName()); | |||||
backWorkNoticeInfo.setMsg(backMsg); | |||||
// 放入系统通知表中,保存记录 | |||||
Notify notify = assemblyAuditNotify(userId, declaredProject, backMsg); | |||||
notify.setType(MsgTypeEnum.PROJECT_REVIEW_BACK.name()); | |||||
notifyService.save(notify); | |||||
// 放入工作通知暂存表中,通过扫表异步发送 | |||||
workNoticeStagingService.addByWorkNotice(backWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW_BACK); | |||||
//发送消息 | |||||
noticeManage.sendNotice(instance.getStartUserId(),userId,declaredProject,instance.getProcessDefinitionName(), | |||||
BACK_MSG_TEMPLATE,MsgTypeEnum.PROJECT_REVIEW_BACK); | |||||
} | } | ||||
@@ -345,67 +297,6 @@ public class HandlerManage { | |||||
projectService.updateById(declaredProject); | projectService.updateById(declaredProject); | ||||
} | } | ||||
/** | |||||
* 装配项目审核工作通知 | |||||
* @param userId | |||||
* @param project | |||||
* @param msg | |||||
*/ | |||||
private Notify assemblyAuditNotify(Long userId, Project project, String msg) { | |||||
Notify notify = new Notify(); | |||||
notify.setTitle(AUDIT_WORK_TITLE); | |||||
notify.setUserId(userId); | |||||
notify.setContent(msg); | |||||
notify.setReaded(Boolean.FALSE); | |||||
notify.setCreateTime(LocalDateTime.now()); | |||||
ProjectAuditMsgExtraDTO msgExtraDto = new ProjectAuditMsgExtraDTO(); | |||||
msgExtraDto.setProjectId(project.getId()); | |||||
msgExtraDto.setInstanceId(project.getInstCode()); | |||||
String extraJson = JSON.toJSONString(msgExtraDto); | |||||
notify.setExtraInfo(extraJson); | |||||
return notify; | |||||
} | |||||
/** | |||||
* 获取发送浙政钉工作通知的信息 | |||||
* | |||||
* @param currentEmployeeCode | |||||
* @return com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo | |||||
* @author CMM | |||||
* @since 2023/02/15 14:04 | |||||
*/ | |||||
public WorkNoticeInfo getSendWorkNoticeInfo(String currentEmployeeCode) { | |||||
UserInfo auditUserInfo = userInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getEmployeeCode,currentEmployeeCode).last("limit 1")); | |||||
if (Objects.isNull(auditUserInfo)) { | |||||
throw new BizException("该用户不存在!"); | |||||
} | |||||
WorkNoticeInfo workNoticeInfo = new WorkNoticeInfo(); | |||||
Long accountId = auditUserInfo.getAccountId(); | |||||
if (Objects.isNull(accountId)) { | |||||
throw new BizException("该用户没有录入浙政钉信息!"); | |||||
} | |||||
workNoticeInfo.setAccountId(accountId); | |||||
// 根据浙政钉用户ID获取部门code | |||||
DingEmployeeInfo employeeInfo = dingEmployeeInfoService.getOne(Wrappers.lambdaQuery(DingEmployeeInfo.class) | |||||
.eq(DingEmployeeInfo::getAccountId, accountId) | |||||
.eq(DingEmployeeInfo::getMainJob,String.valueOf(Boolean.TRUE)) | |||||
.last("limit 1")); | |||||
String organizationCode = employeeInfo.getOrganizationCode(); | |||||
workNoticeInfo.setOrganizationCode(organizationCode); | |||||
// 根据部门code获取部门名称 | |||||
DingOrganization dingOrganization = dingOrganizationService.getOne(Wrappers.lambdaQuery(DingOrganization.class) | |||||
.eq(DingOrganization::getOrganizationCode, organizationCode)); | |||||
String organizationName = dingOrganization.getOrganizationName(); | |||||
workNoticeInfo.setOrganizationName(organizationName); | |||||
// 构建唯一的消息ID | |||||
String bizMsgId = "ZD_WORK_NOTICE_" + StrUtil.UNDERLINE + organizationCode + StrUtil.UNDERLINE | |||||
+ organizationName + accountId + StrUtil.UNDERLINE + System.currentTimeMillis(); | |||||
workNoticeInfo.setBizMsgId(bizMsgId); | |||||
String receiverUserId = String.valueOf(accountId); | |||||
workNoticeInfo.setReceiverUserId(receiverUserId); | |||||
return workNoticeInfo; | |||||
} | |||||
public void deleteBackComments(List<HistoricVariableInstance> approves) { | public void deleteBackComments(List<HistoricVariableInstance> approves) { | ||||
if(CollUtil.isNotEmpty(approves)){ | if(CollUtil.isNotEmpty(approves)){ | ||||
for(HistoricVariableInstance approve : approves){ | for(HistoricVariableInstance approve : approves){ | ||||
@@ -209,6 +209,7 @@ public class TodoCenterManage { | |||||
Project projectInfo = projectInfoMap.get(d.getInstanceId()); | Project projectInfo = projectInfoMap.get(d.getInstanceId()); | ||||
ResToBeProcessedVO res = new ResToBeProcessedVO(); | ResToBeProcessedVO res = new ResToBeProcessedVO(); | ||||
BeanUtils.copyProperties(projectInfo, res); | BeanUtils.copyProperties(projectInfo, res); | ||||
res.setInstCode(d.getInstanceId()); | |||||
res.setProjectId(projectInfo.getId()); | res.setProjectId(projectInfo.getId()); | ||||
res.setBuildOrg(projectInfo.getBuildOrgName()); | res.setBuildOrg(projectInfo.getBuildOrgName()); | ||||
res.setDeclaredAmount(projectInfo.getDeclareAmount()); | res.setDeclaredAmount(projectInfo.getDeclareAmount()); | ||||
@@ -524,6 +525,7 @@ public class TodoCenterManage { | |||||
ResToBeProcessedVO res = new ResToBeProcessedVO(); | ResToBeProcessedVO res = new ResToBeProcessedVO(); | ||||
Project projectInfo = projectInfoMap.get(d.getInstanceId()); | Project projectInfo = projectInfoMap.get(d.getInstanceId()); | ||||
BeanUtils.copyProperties(projectInfo, res); | BeanUtils.copyProperties(projectInfo, res); | ||||
res.setInstCode(d.getInstanceId()); | |||||
res.setBuildOrg(projectInfo.getBuildOrgName()); | res.setBuildOrg(projectInfo.getBuildOrgName()); | ||||
res.setDeclaredAmount(projectInfo.getDeclareAmount()); | res.setDeclaredAmount(projectInfo.getDeclareAmount()); | ||||
res.setProjectId(projectInfo.getId()); | res.setProjectId(projectInfo.getId()); | ||||
@@ -802,6 +804,7 @@ public class TodoCenterManage { | |||||
ResToBeProcessedVO res = new ResToBeProcessedVO(); | ResToBeProcessedVO res = new ResToBeProcessedVO(); | ||||
Project project = projectInfoMap.get(d.getInstanceId()); | Project project = projectInfoMap.get(d.getInstanceId()); | ||||
BeanUtils.copyProperties(project, res); | BeanUtils.copyProperties(project, res); | ||||
res.setInstCode(d.getInstanceId()); | |||||
res.setNodeId(d.getNodeId()); | res.setNodeId(d.getNodeId()); | ||||
res.setProjectId(project.getId()); | res.setProjectId(project.getId()); | ||||
res.setBuildOrg(project.getBuildOrgName()); | res.setBuildOrg(project.getBuildOrgName()); | ||||
@@ -416,6 +416,8 @@ public class UserInfoManage { | |||||
resUserDetailVO.setOrgCode(userFullInfo.getOrganizationCode()); | resUserDetailVO.setOrgCode(userFullInfo.getOrganizationCode()); | ||||
resUserDetailVO.setOrgName(userFullInfo.getOrganizationName()); | resUserDetailVO.setOrgName(userFullInfo.getOrganizationName()); | ||||
resUserDetailVO.setRegionCode(userFullInfo.getRegionCode()); | resUserDetailVO.setRegionCode(userFullInfo.getRegionCode()); | ||||
resUserDetailVO.setRegionName(regionCacheHelper.getRegionName(userFullInfo.getRegionCode() | |||||
,RegionConst.RL_COUNTY)); | |||||
resUserDetailVO.setEmpPosUnitCode(userFullInfo.getEmpPosUnitCode()); | resUserDetailVO.setEmpPosUnitCode(userFullInfo.getEmpPosUnitCode()); | ||||
resUserDetailVO.setEmpPosUnitName(userFullInfo.getEmpPosUnitName()); | resUserDetailVO.setEmpPosUnitName(userFullInfo.getEmpPosUnitName()); | ||||
} | } | ||||
@@ -4,9 +4,11 @@ import com.ningdatech.pmapi.common.constant.RegionConst; | |||||
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 org.apache.commons.lang3.StringUtils; | |||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Objects; | |||||
/** | /** | ||||
* @author liuxinxin | * @author liuxinxin | ||||
@@ -40,6 +42,7 @@ public class ResUserDetailVO { | |||||
@ApiModelProperty("所属区域") | @ApiModelProperty("所属区域") | ||||
private Long regionId; | private Long regionId; | ||||
private String regionCode; | private String regionCode; | ||||
private String regionName; | |||||
@ApiModelProperty("用户任职所在单位code") | @ApiModelProperty("用户任职所在单位code") | ||||
private String empPosUnitCode; | private String empPosUnitCode; | ||||
@@ -51,6 +51,7 @@ public class WorkbenchManage { | |||||
public WorkbenchVO getWorkbenchData(Integer year){ | public WorkbenchVO getWorkbenchData(Integer year){ | ||||
WorkbenchVO res = new WorkbenchVO(); | WorkbenchVO res = new WorkbenchVO(); | ||||
UserInfoDetails user = LoginUserUtil.loginUserDetail(); | |||||
//1.待办中心数据 | //1.待办中心数据 | ||||
TodoCenterStatisticsVO statisticsVO = todoCenterManage.todoCenterStatistics(); | TodoCenterStatisticsVO statisticsVO = todoCenterManage.todoCenterStatistics(); | ||||
@@ -70,6 +71,7 @@ public class WorkbenchManage { | |||||
projectListReq.setPageNumber(1); | projectListReq.setPageNumber(1); | ||||
projectListReq.setPageSize(5); | projectListReq.setPageSize(5); | ||||
projectListReq.setProjectYear(year); | projectListReq.setProjectYear(year); | ||||
projectListReq.setBuildOrgCode(user.getEmpPosUnitCode()); | |||||
res.setProjects(projectLibManage.projectLibListWithPermission(projectListReq).getRecords().stream().collect(Collectors.toList())); | res.setProjects(projectLibManage.projectLibListWithPermission(projectListReq).getRecords().stream().collect(Collectors.toList())); | ||||
//3.所有公告按类型分 | //3.所有公告按类型分 | ||||
@@ -1,9 +1,9 @@ | |||||
package com.ningdatech.pmapi.statemachine; | package com.ningdatech.pmapi.statemachine; | ||||
import com.alibaba.fastjson.JSON; | import com.alibaba.fastjson.JSON; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.ningdatech.pmapi.AppTests; | import com.ningdatech.pmapi.AppTests; | ||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||
@@ -32,4 +32,14 @@ public class StateMachineTest extends AppTests { | |||||
System.out.println(String.format("project:%s", JSON.toJSONString(project))); | System.out.println(String.format("project:%s", JSON.toJSONString(project))); | ||||
projectService.updateById(project); | projectService.updateById(project); | ||||
} | } | ||||
@Test | |||||
public void yyyyyy(){ | |||||
Project project = projectService.getById(400); | |||||
projectService.update(Wrappers.lambdaUpdate(Project.class) | |||||
.set(Project::getNewest,Boolean.FALSE) | |||||
.ne(Project::getId,project.getId()) | |||||
.eq(Project::getProjectCode,project.getProjectCode())); | |||||
System.out.println(project); | |||||
} | |||||
} | } |
@@ -13,6 +13,7 @@ import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | ||||
import com.ningdatech.pmapi.sys.manage.NoticeManage; | |||||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | ||||
import com.ningdatech.pmapi.todocenter.manage.HandlerManage; | import com.ningdatech.pmapi.todocenter.manage.HandlerManage; | ||||
import com.ningdatech.pmapi.todocenter.manage.TodoCenterManage; | import com.ningdatech.pmapi.todocenter.manage.TodoCenterManage; | ||||
@@ -72,7 +73,7 @@ public class TodoCenterTest extends AppTests { | |||||
private HistoryService historyService; | private HistoryService historyService; | ||||
@Autowired | @Autowired | ||||
private HandlerManage handlerManage; | |||||
private NoticeManage handlerManage; | |||||
@Test | @Test | ||||
public void sendWorkNoticeTest() throws ExecutionException, InterruptedException { | public void sendWorkNoticeTest() throws ExecutionException, InterruptedException { | ||||
@@ -175,6 +175,12 @@ | |||||
<artifactId>html2pdf</artifactId> | <artifactId>html2pdf</artifactId> | ||||
<version>2.0.2</version> | <version>2.0.2</version> | ||||
</dependency> | </dependency> | ||||
<!--导入导出--> | |||||
<dependency> | |||||
<groupId>cn.afterturn</groupId> | |||||
<artifactId>easypoi-base</artifactId> | |||||
<version>4.2.0</version> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
</dependencyManagement> | </dependencyManagement> | ||||