@@ -10,7 +10,16 @@ public class StateMachineConst { | |||
private StateMachineConst() { | |||
} | |||
public static final String PROJECT_DECLARE = "projectDeclare"; | |||
public static final String APPLICATION_DECLARE = "applicationDeclare"; | |||
public static class MessageHeader { | |||
private MessageHeader() { | |||
} | |||
public static final String PURCHASE = "purchaseInfo"; | |||
public static final String EXTRA_ARGS = "extraArgs"; | |||
public static final String PROJECT_DECLARE = "projectDeclare"; | |||
public static final String APPLICATION_DECLARE = "applicationDeclare"; | |||
} | |||
} |
@@ -11,6 +11,7 @@ import org.springframework.messaging.Message; | |||
import org.springframework.statemachine.annotation.OnTransition; | |||
import org.springframework.statemachine.annotation.WithStateMachine; | |||
/** | |||
* 项目申报状态机action集合类 | |||
* | |||
@@ -22,14 +23,18 @@ import org.springframework.statemachine.annotation.WithStateMachine; | |||
@WithStateMachine(id = ProjectStateMachineBuilderImpl.MACHINE_ID) | |||
public class ProjectStateChangeAction { | |||
private static final String PROJECT_DECLARE = StateMachineConst.PROJECT_DECLARE; | |||
public static Project getProject(Message<ProjectStateChangeEvent> message) { | |||
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | |||
Project project = (Project) message.getHeaders().get(StateMachineConst.MessageHeader.PROJECT_DECLARE); | |||
Assert.notNull(project, "未获取到需要状态变更的项目信息"); | |||
return project; | |||
} | |||
public static <T> T getExtraArgs(Message<ProjectStateChangeEvent> message) { | |||
T extraArgs = (T) message.getHeaders().get(StateMachineConst.MessageHeader.EXTRA_ARGS); | |||
Assert.notNull(extraArgs, "未获取到需要状态变更的附件参数"); | |||
return extraArgs; | |||
} | |||
@OnTransition(source = "TO_BE_DECLARED", target = "ON_COMPLIANCE_REVIEW") | |||
public void PROJECT_APPLICATION_SUBMIT(Message<ProjectStateChangeEvent> message) { | |||
@@ -62,10 +67,10 @@ public class ProjectStateChangeAction { | |||
project.setStatus(ProjectStatus.ON_EXPERT_REVIEW.getCode()); | |||
} | |||
@OnTransition(source = "EXPERT_REVIEW_FAILED", target = "ON_EXPERT_REVIEW") | |||
@OnTransition(source = "EXPERT_REVIEW_AFTER_MODIFY", target = "WITHOUT_EXPERT_REVIEW") | |||
public void EXPERT_REVIEW_RESUBMIT(Message<ProjectStateChangeEvent> message) { | |||
Project project = getProject(message); | |||
project.setStatus(ProjectStatus.ON_EXPERT_REVIEW.getCode()); | |||
project.setStatus(ProjectStatus.WITHOUT_EXPERT_REVIEW.getCode()); | |||
} | |||
@OnTransition(source = "ON_EXPERT_REVIEW", target = "EXPERT_REVIEW_FAILED") | |||
@@ -74,6 +79,12 @@ public class ProjectStateChangeAction { | |||
project.setStatus(ProjectStatus.EXPERT_REVIEW_FAILED.getCode()); | |||
} | |||
@OnTransition(source = "ON_EXPERT_REVIEW", target = "EXPERT_REVIEW_AFTER_MODIFY") | |||
public void EXPERT_REVIEW_AFTER_MODIFY(Message<ProjectStateChangeEvent> message) { | |||
Project project = getProject(message); | |||
project.setStatus(ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY.getCode()); | |||
} | |||
@OnTransition(source = "ON_EXPERT_REVIEW", target = "WITHOUT_PROJECT_REVIEW") | |||
public void EXPERT_REVIEW_PASS(Message<ProjectStateChangeEvent> message) { | |||
Project project = getProject(message); | |||
@@ -3,6 +3,8 @@ package com.hz.pm.api.common.statemachine.builder.impl; | |||
import com.hz.pm.api.common.statemachine.builder.BaseStateMachineBuilder; | |||
import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent; | |||
import com.hz.pm.api.common.statemachine.factory.ProjectGuardFactory; | |||
import com.hz.pm.api.common.statemachine.factory.ProjectGuardFactory.ExpertReviewToFailed; | |||
import com.hz.pm.api.common.statemachine.factory.ProjectGuardFactory.ExpertReviewToModify; | |||
import com.hz.pm.api.common.statemachine.factory.ProjectGuardFactory.ProjectPurchaseToAcceptGuard; | |||
import com.hz.pm.api.projectlib.model.entity.Project; | |||
import com.hz.pm.api.projectlib.model.enumeration.status.ProjectStatus; | |||
@@ -102,16 +104,24 @@ public class ProjectStateMachineBuilderImpl implements BaseStateMachineBuilder<P | |||
.source(ProjectStatus.WITHOUT_EXPERT_REVIEW) | |||
.target(ProjectStatus.ON_EXPERT_REVIEW) | |||
.event(ProjectStateChangeEvent.EXPERT_REVIEW_SUBMIT).and() | |||
// 重新提交项目评审 | |||
// 重新提交专家评审 | |||
.withExternal() | |||
.source(ProjectStatus.EXPERT_REVIEW_FAILED) | |||
.target(ProjectStatus.ON_EXPERT_REVIEW) | |||
.source(ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY) | |||
.target(ProjectStatus.WITHOUT_EXPERT_REVIEW) | |||
.event(ProjectStateChangeEvent.EXPERT_REVIEW_RESUBMIT).and() | |||
// 项目评审不通过 | |||
// 专家评审不通过 | |||
.withExternal() | |||
.source(ProjectStatus.ON_EXPERT_REVIEW) | |||
.target(ProjectStatus.EXPERT_REVIEW_FAILED) | |||
.event(ProjectStateChangeEvent.EXPERT_REVIEW_FAILED).and() | |||
.event(ProjectStateChangeEvent.EXPERT_REVIEW_FAILED) | |||
.guard(new ExpertReviewToFailed()) | |||
.and() | |||
.withExternal() | |||
.source(ProjectStatus.ON_EXPERT_REVIEW) | |||
.target(ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY) | |||
.event(ProjectStateChangeEvent.EXPERT_REVIEW_FAILED) | |||
.guard(new ExpertReviewToModify()) | |||
.and() | |||
// 项目评审通过 | |||
.withExternal() | |||
.source(ProjectStatus.ON_EXPERT_REVIEW) | |||
@@ -185,22 +195,26 @@ public class ProjectStateMachineBuilderImpl implements BaseStateMachineBuilder<P | |||
.withExternal() | |||
.source(ProjectStatus.ON_ADAPTING) | |||
.target(ProjectStatus.TO_BE_FIRST_INSPECTED) | |||
.event(ProjectStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM).and() | |||
.event(ProjectStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM) | |||
.and() | |||
// 上传初验材料 | |||
.withExternal() | |||
.source(ProjectStatus.TO_BE_FIRST_INSPECTED) | |||
.target(ProjectStatus.ON_PILOT_RUNNING) | |||
.event(ProjectStateChangeEvent.SUBMIT_FIRST_INSPECTED_FILES).and() | |||
.event(ProjectStateChangeEvent.SUBMIT_FIRST_INSPECTED_FILES) | |||
.and() | |||
// 待终验终验申请,从待终验到终验审核中 | |||
.withExternal() | |||
.source(ProjectStatus.ON_PILOT_RUNNING) | |||
.target(ProjectStatus.ON_FINALLY_INSPECTED) | |||
.event(ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION).and() | |||
.event(ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION) | |||
.and() | |||
// 终审审核通过,从终审审核中到已归档 | |||
.withExternal() | |||
.source(ProjectStatus.ON_FINALLY_INSPECTED) | |||
.target(ProjectStatus.ARCHIVED) | |||
.event(ProjectStateChangeEvent.FINAL_ACCEPTANCE_PASS).and() | |||
.event(ProjectStateChangeEvent.FINAL_ACCEPTANCE_PASS) | |||
.and() | |||
// 终审审核不通过,从终审审核中到终审审核不通过 | |||
.withExternal() | |||
.source(ProjectStatus.ON_FINALLY_INSPECTED) | |||
@@ -46,7 +46,7 @@ public enum ProjectStateChangeEvent implements AbstractStateChangeEvent { | |||
/** | |||
* @see ProjectStateChangeAction#EXPERT_REVIEW_RESUBMIT(Message) | |||
*/ | |||
EXPERT_REVIEW_RESUBMIT(ProjectStatus.EXPERT_REVIEW_FAILED.getCode(), null, null), | |||
EXPERT_REVIEW_RESUBMIT(ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY.getCode(), null, null), | |||
/** | |||
* @see ProjectStateChangeAction#EXPERT_REVIEW_FAILED(Message) | |||
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.hz.pm.api.common.statemachine.action.ProjectStateChangeAction; | |||
import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent; | |||
import com.hz.pm.api.meeting.entity.enumeration.ExpertReviewResultEnum; | |||
import com.hz.pm.api.projectdeclared.model.entity.Purchase; | |||
import com.hz.pm.api.projectdeclared.model.enumerization.BidTypeEnum; | |||
import com.hz.pm.api.projectdeclared.service.IPurchaseService; | |||
@@ -36,6 +37,28 @@ public class ProjectGuardFactory { | |||
} | |||
@AllArgsConstructor | |||
public static class ExpertReviewToFailed implements Guard<ProjectStatus, ProjectStateChangeEvent> { | |||
@Override | |||
public boolean evaluate(StateContext<ProjectStatus, ProjectStateChangeEvent> ctx) { | |||
Integer reviewResult = ProjectStateChangeAction.getExtraArgs(ctx.getMessage()); | |||
return ExpertReviewResultEnum.FAILED.eq(reviewResult); | |||
} | |||
} | |||
@AllArgsConstructor | |||
public static class ExpertReviewToModify implements Guard<ProjectStatus, ProjectStateChangeEvent> { | |||
@Override | |||
public boolean evaluate(StateContext<ProjectStatus, ProjectStateChangeEvent> ctx) { | |||
Integer reviewResult = ProjectStateChangeAction.getExtraArgs(ctx.getMessage()); | |||
return ExpertReviewResultEnum.REVIEW_AFTER_MODIFY.eq(reviewResult); | |||
} | |||
} | |||
@AllArgsConstructor | |||
public static class ProjectPurchaseToAcceptGuard implements Guard<ProjectStatus, ProjectStateChangeEvent> { | |||
private IPurchaseService purchaseService; | |||
@@ -37,8 +37,11 @@ public interface AbstractStateMachineUtil<O, E extends Enum<E> & AbstractStateCh | |||
return this; | |||
} | |||
//通过审核 | |||
default void pass(O obj) { | |||
pass(obj, null); | |||
} | |||
default <T> void pass(O obj, T extraArgs) { | |||
try { | |||
synchronized (getLockClass()) { | |||
execute(obj, AbstractStateChangeEvent.getPassEvent(eventClass(), statusFunction().apply(obj))); | |||
@@ -49,12 +52,14 @@ public interface AbstractStateMachineUtil<O, E extends Enum<E> & AbstractStateCh | |||
} | |||
} | |||
//拒绝 | |||
default void reject(O obj) { | |||
reject(obj, null); | |||
} | |||
default <T> void reject(O obj, T extraArgs) { | |||
try { | |||
synchronized (getLockClass()) { | |||
execute(obj, AbstractStateChangeEvent.getRejectEvent(eventClass(), statusFunction().apply(obj))); | |||
execute(obj, AbstractStateChangeEvent.getRejectEvent(eventClass(), statusFunction().apply(obj)), extraArgs); | |||
} | |||
} catch (Exception e) { | |||
LOG.error("状态机拒绝失败", e); | |||
@@ -76,7 +81,10 @@ public interface AbstractStateMachineUtil<O, E extends Enum<E> & AbstractStateCh | |||
Function<O, Integer> statusFunction(); | |||
void execute(O o, E event) throws Exception; | |||
default void execute(O o, E event) throws Exception { | |||
execute(o, event, null); | |||
} | |||
<T> void execute(O o, E event, T extraArgs) throws Exception; | |||
} |
@@ -1,5 +1,6 @@ | |||
package com.hz.pm.api.common.statemachine.util; | |||
import com.hz.pm.api.common.model.constant.StateMachineConst; | |||
import com.hz.pm.api.common.statemachine.builder.impl.AdaptStateMachineBuilderImpl; | |||
import com.hz.pm.api.common.statemachine.event.AdaptStateChangeEvent; | |||
import com.hz.pm.api.projectdeclared.model.entity.Purchase; | |||
@@ -29,8 +30,6 @@ import java.util.function.Function; | |||
@Component | |||
public class AdaptStateMachineUtil implements AbstractStateMachineUtil<Purchase, AdaptStateChangeEvent> { | |||
public static final String PURCHASE = "purchaseInfo"; | |||
//================================================================================================================== | |||
private final StateMachinePersister<TenderAdaptStatus, AdaptStateChangeEvent, Purchase> stateMachinePersister; | |||
@@ -50,7 +49,7 @@ public class AdaptStateMachineUtil implements AbstractStateMachineUtil<Purchase, | |||
} | |||
@Override | |||
public void execute(Purchase purchase, AdaptStateChangeEvent event) throws Exception { | |||
public <T> void execute(Purchase purchase, AdaptStateChangeEvent event, T extraArgs) throws Exception { | |||
PurchaseStatusChange change = new PurchaseStatusChange(); | |||
change.setBeforeStatus(purchase.getAdaptStatus()); | |||
change.setEvent(event.name()); | |||
@@ -59,7 +58,8 @@ public class AdaptStateMachineUtil implements AbstractStateMachineUtil<Purchase, | |||
change.setProjectCode(ProjectIdCodeCacheUtil.get(purchase.getProjectId())); | |||
change.setCreateOn(LocalDateTime.now()); | |||
Message<AdaptStateChangeEvent> message = MessageBuilder.withPayload(event) | |||
.setHeader(PURCHASE, purchase) | |||
.setHeader(StateMachineConst.MessageHeader.PURCHASE, purchase) | |||
.setHeader(StateMachineConst.MessageHeader.EXTRA_ARGS, extraArgs) | |||
.build(); | |||
//初始化状态机 | |||
stateMachinePersister.restore(stateMachine, purchase); | |||
@@ -8,7 +8,6 @@ import com.hz.pm.api.projectlib.model.entity.ProjectStatusChange; | |||
import com.hz.pm.api.projectlib.model.enumeration.status.ProjectStatus; | |||
import com.hz.pm.api.projectlib.service.IProjectApplicationService; | |||
import com.hz.pm.api.projectlib.service.IProjectStatusChangeService; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.messaging.Message; | |||
import org.springframework.messaging.support.MessageBuilder; | |||
@@ -29,10 +28,6 @@ import java.util.function.Function; | |||
@Component | |||
public class ProjectStateMachineUtil implements AbstractStateMachineUtil<Project, ProjectStateChangeEvent> { | |||
private static final String PROJECT_DECLARE = StateMachineConst.PROJECT_DECLARE; | |||
private static final String APPLICATION_DECLARE = StateMachineConst.APPLICATION_DECLARE; | |||
//================================================================================================================== | |||
private final StateMachinePersister<ProjectStatus, ProjectStateChangeEvent, Project> stateMachinePersister; | |||
@@ -55,14 +50,15 @@ public class ProjectStateMachineUtil implements AbstractStateMachineUtil<Project | |||
} | |||
@Override | |||
public void execute(Project project, ProjectStateChangeEvent event) throws Exception { | |||
public <T> void execute(Project project, ProjectStateChangeEvent event, T extraArgs) throws Exception { | |||
// 将状态变更记录保存到项目状态变更表中 | |||
ProjectStatusChange change = new ProjectStatusChange(); | |||
change.setBeforeStatus(project.getStatus()); | |||
// 获取TO状态机 | |||
Message<ProjectStateChangeEvent> message = MessageBuilder.withPayload(event) | |||
.setHeader(PROJECT_DECLARE, project) | |||
.setHeader(APPLICATION_DECLARE, projectApplicationService.getApplicationsByProject(project)) | |||
.setHeader(StateMachineConst.MessageHeader.PROJECT_DECLARE, project) | |||
.setHeader(StateMachineConst.MessageHeader.EXTRA_ARGS, extraArgs) | |||
.setHeader(StateMachineConst.MessageHeader.APPLICATION_DECLARE, projectApplicationService.getApplicationsByProject(project)) | |||
.build(); | |||
//初始化状态机 | |||
stateMachinePersister.restore(stateMachine, project); | |||
@@ -1,5 +1,6 @@ | |||
package com.hz.pm.api.common.statemachine.util; | |||
import com.hz.pm.api.common.model.constant.StateMachineConst; | |||
import com.hz.pm.api.common.statemachine.builder.impl.SelfTestStateMachineBuilderImpl; | |||
import com.hz.pm.api.common.statemachine.event.SelfTestStateChangeEvent; | |||
import com.hz.pm.api.projectdeclared.model.entity.Purchase; | |||
@@ -7,7 +8,6 @@ import com.hz.pm.api.projectdeclared.utils.ProjectIdCodeCacheUtil; | |||
import com.hz.pm.api.projectlib.entity.PurchaseStatusChange; | |||
import com.hz.pm.api.projectlib.model.enumeration.status.TenderSelfTestStatus; | |||
import com.hz.pm.api.projectlib.service.IPurchaseStatusChangeService; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.messaging.Message; | |||
import org.springframework.messaging.support.MessageBuilder; | |||
@@ -30,8 +30,6 @@ import java.util.function.Function; | |||
@Component | |||
public class SelfTestStateMachineUtil implements AbstractStateMachineUtil<Purchase, SelfTestStateChangeEvent> { | |||
public static final String PURCHASE = "purchaseInfo"; | |||
//================================================================================================================== | |||
private final IPurchaseStatusChangeService purchaseStatusChangeService; | |||
@@ -50,7 +48,7 @@ public class SelfTestStateMachineUtil implements AbstractStateMachineUtil<Purcha | |||
} | |||
@Override | |||
public void execute(Purchase purchase, SelfTestStateChangeEvent event) throws Exception { | |||
public <T> void execute(Purchase purchase, SelfTestStateChangeEvent event, T extraArgs) throws Exception { | |||
// 获取TO状态机 | |||
PurchaseStatusChange change = new PurchaseStatusChange(); | |||
change.setBeforeStatus(purchase.getSelfTestStatus()); | |||
@@ -60,7 +58,8 @@ public class SelfTestStateMachineUtil implements AbstractStateMachineUtil<Purcha | |||
change.setProjectCode(ProjectIdCodeCacheUtil.get(purchase.getProjectId())); | |||
change.setCreateOn(LocalDateTime.now()); | |||
Message<SelfTestStateChangeEvent> message = MessageBuilder.withPayload(event) | |||
.setHeader(PURCHASE, purchase) | |||
.setHeader(StateMachineConst.MessageHeader.PURCHASE, purchase) | |||
.setHeader(StateMachineConst.MessageHeader.EXTRA_ARGS, extraArgs) | |||
.build(); | |||
//初始化状态机 | |||
stateMachinePersister.restore(stateMachine, purchase); | |||
@@ -51,7 +51,7 @@ public class TenderStateMachineUtil implements AbstractStateMachineUtil<Purchase | |||
} | |||
@Override | |||
public void execute(Purchase purchase, TenderStateChangeEvent event) throws Exception { | |||
public <T> void execute(Purchase purchase, TenderStateChangeEvent event, T extraArgs) throws Exception { | |||
// 获取TO状态机 | |||
PurchaseStatusChange change = new PurchaseStatusChange(); | |||
change.setBeforeStatus(purchase.getStatus()); | |||
@@ -44,7 +44,7 @@ public class TestValidStateMachineUtil implements AbstractStateMachineUtil<Purch | |||
} | |||
@Override | |||
public void execute(Purchase purchase, TestValidStateChangeEvent event) throws Exception { | |||
public <T> void execute(Purchase purchase, TestValidStateChangeEvent event, T extraArgs) throws Exception { | |||
PurchaseStatusChange change = new PurchaseStatusChange(); | |||
change.setBeforeStatus(purchase.getTestValidStatus()); | |||
change.setEvent(event.name()); | |||
@@ -1,5 +1,6 @@ | |||
package com.hz.pm.api.common.statemachine.util; | |||
import com.hz.pm.api.common.model.constant.StateMachineConst; | |||
import com.hz.pm.api.common.statemachine.builder.impl.XcfhxStateMachineBuilderImpl; | |||
import com.hz.pm.api.common.statemachine.event.XcfhxStateChangeEvent; | |||
import com.hz.pm.api.projectdeclared.model.entity.Purchase; | |||
@@ -7,7 +8,6 @@ import com.hz.pm.api.projectdeclared.utils.ProjectIdCodeCacheUtil; | |||
import com.hz.pm.api.projectlib.entity.PurchaseStatusChange; | |||
import com.hz.pm.api.projectlib.model.enumeration.status.TenderXcfhxApplyStatus; | |||
import com.hz.pm.api.projectlib.service.IPurchaseStatusChangeService; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.messaging.Message; | |||
import org.springframework.messaging.support.MessageBuilder; | |||
@@ -51,7 +51,7 @@ public class XcfhxStateMachineUtil implements AbstractStateMachineUtil<Purchase, | |||
} | |||
@Override | |||
public void execute(Purchase purchase, XcfhxStateChangeEvent event) throws Exception { | |||
public <T> void execute(Purchase purchase, XcfhxStateChangeEvent event, T extraArgs) throws Exception { | |||
PurchaseStatusChange change = new PurchaseStatusChange(); | |||
change.setBeforeStatus(purchase.getXcfhxApplyStatus()); | |||
change.setEvent(event.name()); | |||
@@ -60,7 +60,8 @@ public class XcfhxStateMachineUtil implements AbstractStateMachineUtil<Purchase, | |||
change.setProjectCode(ProjectIdCodeCacheUtil.get(purchase.getProjectId())); | |||
change.setCreateOn(LocalDateTime.now()); | |||
Message<XcfhxStateChangeEvent> message = MessageBuilder.withPayload(event) | |||
.setHeader(PURCHASE, purchase) | |||
.setHeader(StateMachineConst.MessageHeader.PURCHASE, purchase) | |||
.setHeader(StateMachineConst.MessageHeader.EXTRA_ARGS, extraArgs) | |||
.build(); | |||
//初始化状态机 | |||
stateMachinePersister.restore(stateMachine, purchase); | |||
@@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModelProperty; | |||
import lombok.Data; | |||
import java.math.BigDecimal; | |||
import java.time.LocalDate; | |||
import java.time.LocalDateTime; | |||
/** | |||
* <p> | |||
@@ -39,4 +41,7 @@ public class ProjectReviewResultDTO { | |||
private String attachFiles; | |||
@ApiModelProperty("更新时间") | |||
private LocalDateTime updateOn; | |||
} |
@@ -0,0 +1,31 @@ | |||
package com.hz.pm.api.meeting.entity.enumeration; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Getter; | |||
/** | |||
* <p> | |||
* ExpertReviewResultEnum | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 15:33 2024/11/20 | |||
*/ | |||
@Getter | |||
@AllArgsConstructor | |||
public enum ExpertReviewResultEnum { | |||
PASS("通过", 1), | |||
FAILED("不通过", 0), | |||
REVIEW_AFTER_MODIFY("修改方案后重新评审", 2); | |||
private final String value; | |||
private final Integer code; | |||
public boolean eq(Integer code) { | |||
return this.getCode().equals(code); | |||
} | |||
} |
@@ -27,7 +27,7 @@ public class ProjectReviewInfoReq { | |||
@ApiModelProperty("技术方案可行性") | |||
private String techFeasibility; | |||
@ApiModelProperty("审核结果:1 通过、0 不通过") | |||
@ApiModelProperty("审核结果:1 通过、0 不通过、2 修改方案后重新评审") | |||
@NotNull(message = "评审结果不能为空") | |||
private Integer reviewResult; | |||
@@ -1014,7 +1014,7 @@ public class MeetingManage { | |||
LambdaQueryWrapper<Project> query = Wrappers.lambdaQuery(Project.class) | |||
.eq(Project::getNewest, Boolean.TRUE) | |||
.notIn(Project::getStage, ProjectStatus.STOPPED.getCode(), ProjectStatus.CHANGE.getCode()); | |||
UserInfoDetails userDetail = LoginUserUtil.userDetail(); | |||
UserInfoDetails userDetail = LoginUserUtil.userDetailNotNull(); | |||
switch (userDetail.maxAuthRole()) { | |||
case SUPER_ADMIN: | |||
break; | |||
@@ -1101,7 +1101,7 @@ public class MeetingManage { | |||
String sql = String.format("select 1 from meeting m inner join meeting_inner_project mip on" + | |||
" m.is_inner_project = 1 and m.id = mip.meeting_id and nd_project.id = mip.project_id" + | |||
" and m.type = %s and m.status != 3", meetingType); | |||
String sql2 = String.format("1 = (select case when review_result in (0) then 1 else 0 end from " + | |||
String sql2 = String.format("1 = (select case when review_result in (0,2) then 1 else 0 end from " + | |||
" (select ner.review_result from meeting m inner join meeting_inner_project mip on" + | |||
" m.is_inner_project = 1 and m.id = mip.meeting_id and nd_project.id = mip.project_id" + | |||
" and m.type = %s and m.status != 3 left join nd_expert_review ner on ner.meeting_id = m.id " + | |||
@@ -1175,7 +1175,7 @@ public class MeetingManage { | |||
projectStateMachineUtil.pass(project); | |||
SpringUtil.publishEvent(MhTodoSendEvent.of(MHTodoTypeEnum.PROJECT_REVIEW_APPLY, project)); | |||
} else { | |||
projectStateMachineUtil.reject(project); | |||
projectStateMachineUtil.reject(project, req.getReviewResult()); | |||
} | |||
projectService.updateById(project); | |||
meetingInnerProjectService.updateById(mip); | |||
@@ -77,4 +77,11 @@ public class ProjectReviewController { | |||
return projectReviewManage.expertReviewProjectProgressStatistics(req); | |||
} | |||
@ApiOperation("修改后重新提交") | |||
@WebLog("修改后重新提交") | |||
@PostMapping("/resubmitByModify") | |||
public void resubmitByModify(@RequestBody DefaultDeclaredDTO req) { | |||
projectReviewManage.resubmitByModify(req); | |||
} | |||
} |
@@ -2,12 +2,14 @@ package com.hz.pm.api.projectdeclared.manage; | |||
import cn.hutool.core.bean.BeanUtil; | |||
import cn.hutool.core.collection.CollUtil; | |||
import cn.hutool.core.lang.Assert; | |||
import cn.hutool.core.util.StrUtil; | |||
import cn.hutool.extra.spring.SpringUtil; | |||
import com.baomidou.mybatisplus.core.conditions.Wrapper; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||
import com.hz.pm.api.common.enumeration.CommonEnum; | |||
import com.hz.pm.api.common.enumeration.ProjectProcessType; | |||
import com.hz.pm.api.common.exception.ReturnException; | |||
import com.hz.pm.api.common.helper.UserInfoHelper; | |||
@@ -30,6 +32,7 @@ import com.hz.pm.api.projectdeclared.service.IProjectReviewService; | |||
import com.hz.pm.api.projectdeclared.utils.ProjectIdCodeCacheUtil; | |||
import com.hz.pm.api.projectlib.helper.ProjectManageUtil; | |||
import com.hz.pm.api.projectlib.helper.ProjectSaveHelper; | |||
import com.hz.pm.api.projectlib.manage.ProjectLibManage; | |||
import com.hz.pm.api.projectlib.model.dto.ProjectDTO; | |||
import com.hz.pm.api.projectlib.model.entity.Project; | |||
import com.hz.pm.api.projectlib.model.entity.ProjectInst; | |||
@@ -46,6 +49,7 @@ import com.hz.pm.api.user.security.model.UserFullInfoDTO; | |||
import com.hz.pm.api.user.security.model.UserInfoDetails; | |||
import com.hz.pm.api.user.util.LoginUserUtil; | |||
import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.basic.function.VUtils; | |||
import com.ningdatech.basic.model.PageVo; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.wflow.bean.entity.WflowModels; | |||
@@ -85,7 +89,7 @@ public class ProjectReviewManage { | |||
private final UserInfoHelper userInfoHelper; | |||
private final IMeetingInnerProjectService meetingInnerProjectService; | |||
private final ProjectSaveHelper projectSaveHelper; | |||
private final ProjectLibManage projectLibManage; | |||
@Transactional(rollbackFor = Exception.class) | |||
public synchronized void projectReviewApply(DefaultDeclaredDTO req) { | |||
@@ -239,6 +243,7 @@ public class ProjectReviewManage { | |||
List<Project> projects = projectService.list(query); | |||
Map<ProjectStatus, Long> countMap = CollUtils.groupCount(projects, w -> { | |||
if (!ProjectStatus.EXPERT_REVIEW_FAILED.eq(w.getStatus()) | |||
&& !ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY.eq(w.getStatus()) | |||
&& !ProjectStatus.COMPLIANCE_REVIEW_PASSED.eq(w.getStatus()) | |||
&& !ProjectStatus.WITHOUT_EXPERT_REVIEW.eq(w.getStatus()) | |||
&& !ProjectStatus.ON_EXPERT_REVIEW.eq(w.getStatus()) | |||
@@ -255,7 +260,9 @@ public class ProjectReviewManage { | |||
.todoCount(countMap.getOrDefault(ProjectStatus.WITHOUT_EXPERT_REVIEW, 0L)) | |||
.auditCount(countMap.getOrDefault(ProjectStatus.ON_EXPERT_REVIEW, 0L)) | |||
.passedCount(countMap.getOrDefault(ProjectStatus.EXPERT_REVIEW_PASSED, 0L)) | |||
.failedCount(countMap.getOrDefault(ProjectStatus.EXPERT_REVIEW_FAILED, 0L)) | |||
.failedCount(countMap.getOrDefault(ProjectStatus.EXPERT_REVIEW_FAILED, 0L) + | |||
countMap.getOrDefault(ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY, 0L)) | |||
.toBeResubmitCount(countMap.getOrDefault(ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY, 0L)) | |||
.build(); | |||
} | |||
@@ -277,8 +284,9 @@ public class ProjectReviewManage { | |||
if (ProjectStatus.EXPERT_REVIEW_PASSED.eq(status)) { | |||
query.exists(ExistsSqlConst.PROJECT_EXISTS_STATUS_CHANGE + | |||
" and npsc.event = {0}", ProjectStateChangeEvent.EXPERT_REVIEW_PASS); | |||
} else { | |||
query.eq(Project::getStatus, status); | |||
} else if (ProjectStatus.EXPERT_REVIEW_FAILED.eq(status)) { | |||
query.in(Project::getStatus, ProjectStatus.EXPERT_REVIEW_FAILED.getCode(), | |||
ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY.getCode()); | |||
} | |||
} else { | |||
query.exists(ExistsSqlConst.PROJECT_EXISTS_STATUS_CHANGE + | |||
@@ -298,6 +306,7 @@ public class ProjectReviewManage { | |||
projectIds.add(w.getId()); | |||
ProjectLibListItemVO item = BeanUtil.copyProperties(w, ProjectLibListItemVO.class); | |||
if (!ProjectStatus.EXPERT_REVIEW_FAILED.eq(w.getStatus()) | |||
&& !ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY.eq(w.getStatus()) | |||
&& !ProjectStatus.COMPLIANCE_REVIEW_PASSED.eq(w.getStatus()) | |||
&& !ProjectStatus.WITHOUT_EXPERT_REVIEW.eq(w.getStatus()) | |||
&& !ProjectStatus.ON_EXPERT_REVIEW.eq(w.getStatus()) | |||
@@ -322,6 +331,34 @@ public class ProjectReviewManage { | |||
return PageVo.of(records, page.getTotal()); | |||
} | |||
@Transactional(rollbackFor = Exception.class) | |||
public synchronized void resubmitByModify(DefaultDeclaredDTO req) { | |||
ProjectDTO reqProj = req.getProjectInfo(); | |||
Assert.notNull(reqProj.getId(), "项目ID不能为空"); | |||
UserInfoDetails user = LoginUserUtil.userDetailNotNull(); | |||
reqProj.setBuildOrgCode(user.getMhUnitIdStr()); | |||
reqProj.setBuildOrgName(user.getMhUnitName()); | |||
Project oldProj = projectService.getNoNull(reqProj.getId()); | |||
//首先要判断 项目当前状态 是不是 单位内部拒绝 | |||
if (!ProjectStatus.EXPERT_REVIEW_AFTER_MODIFY.eq(oldProj.getStatus())) { | |||
throw ReturnException.wrap("该项目不是修改方案后重新评审状态"); | |||
} | |||
//项目名称去重 | |||
if (StrUtil.isNotBlank(reqProj.getProjectName()) && | |||
!reqProj.getProjectName().equals(oldProj.getProjectName())) { | |||
reqProj.setProjectCode(oldProj.getProjectCode()); | |||
declaredProjectHelper.projectNameDuplicateCheck(reqProj); | |||
} | |||
//判断申报金额 是否等于总的 判断年度支付金额 是否等于总金额 | |||
declaredProjectHelper.checkAmount(reqProj); | |||
// 保存项目相关 | |||
Project newProj = projectLibManage.newProjectWithVersion(reqProj, oldProj, null); | |||
log.info("项目申报提交成功,项目名称:{} 项目ID:{}", newProj.getProjectName(), newProj.getId()); | |||
} | |||
private boolean projectQueryPermission(LambdaQueryWrapper<Project> query, | |||
UserFullInfoDTO user, | |||
Long declaredUnitId) { | |||
@@ -18,15 +18,23 @@ public class ReviewProgressStatisticsVO { | |||
@ApiModelProperty("总数") | |||
private Integer totalCount; | |||
@ApiModelProperty("未上传建设方案盖章件的文件") | |||
private Integer withoutConstructionPlanSealFileCount; | |||
@ApiModelProperty("待提交") | |||
private Long todoCount; | |||
@ApiModelProperty("审核中") | |||
private Long auditCount; | |||
@ApiModelProperty("已通过") | |||
private Long passedCount; | |||
@ApiModelProperty("未通过") | |||
private Long failedCount; | |||
@ApiModelProperty("待重新提交") | |||
private Long toBeResubmitCount; | |||
} |
@@ -836,10 +836,10 @@ public class ProjectLibManage { | |||
Wrapper<MeetingInnerProject> mipQuery = Wrappers.lambdaQuery(MeetingInnerProject.class) | |||
.eq(MeetingInnerProject::getProjectCode, project.getProjectCode()) | |||
.exists(ExistsSqlConst.MEETING_INNER_PROJECT_EXISTS_MEETING + "and m.status != 3") | |||
.orderByDesc(MeetingInnerProject::getId) | |||
.last(BizConst.LIMIT_1); | |||
MeetingInnerProject mip = meetingInnerProjectService.getOne(mipQuery); | |||
retProjectDetail.setReviewDetail(BeanUtil.copyProperties(mip, ProjectReviewResultDTO.class)); | |||
.isNotNull(MeetingInnerProject::getReviewResult) | |||
.orderByDesc(MeetingInnerProject::getId); | |||
List<MeetingInnerProject> mip = meetingInnerProjectService.list(mipQuery); | |||
retProjectDetail.setReviewDetail(BeanUtil.copyToList(mip, ProjectReviewResultDTO.class)); | |||
return retProjectDetail; | |||
} | |||
@@ -1002,6 +1002,14 @@ public class ProjectLibManage { | |||
*/ | |||
public Project newProjectWithVersion(ProjectDTO reqProj, Boolean isConstruct) { | |||
Project oldProj = projectService.getNoNull(reqProj.getId()); | |||
return saveProjectWithNewVersion(reqProj, oldProj, isConstruct); | |||
} | |||
public Project newProjectWithVersion(ProjectDTO reqProj, Project oldProj, Boolean isConstruct) { | |||
return saveProjectWithNewVersion(reqProj, oldProj, isConstruct); | |||
} | |||
private Project saveProjectWithNewVersion(ProjectDTO reqProj, Project oldProj, Boolean isConstruct) { | |||
Project newProj = new Project(); | |||
BeanUtil.copyProperties(oldProj, newProj, CopyOptions.create() | |||
.setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE)); | |||
@@ -1009,8 +1017,13 @@ public class ProjectLibManage { | |||
.setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE)); | |||
newProj.setVersion(oldProj.getVersion() + 1); | |||
newProj.setId(null); | |||
newProj.setCreateOn(LocalDateTime.now()); | |||
newProj.setUpdateOn(LocalDateTime.now()); | |||
LocalDateTime now = LocalDateTime.now(); | |||
Long userId = LoginUserUtil.getUserId(); | |||
newProj.setCreateOn(now); | |||
newProj.setUpdateOn(now); | |||
newProj.setCreateBy(userId); | |||
newProj.setUpdateBy(userId); | |||
newProj.setIsMajorProject(Boolean.FALSE); | |||
newProj.setIsBackReject(Boolean.FALSE); | |||
projectStateMachineUtil.pass(newProj); | |||
projectService.save(newProj); | |||
@@ -1024,7 +1037,6 @@ public class ProjectLibManage { | |||
return newProj; | |||
} | |||
public Project saveProjectWithVersionAndStatus(ProjectDTO projectDto, Integer stageCode, Integer statusCode, Boolean isConstruct) { | |||
Project oldProject = projectService.getNoNull(projectDto.getId()); | |||
Project project = new Project(); | |||
@@ -1057,7 +1069,7 @@ public class ProjectLibManage { | |||
} | |||
@Transactional(rollbackFor = Exception.class) | |||
public Project saveProjectWithVersion(ProjectDTO projectDto, String instanceId, Integer instType, Boolean isConstruct) { | |||
public Project saveProjectWithNewVersion(ProjectDTO projectDto, String instanceId, Integer instType, Boolean isConstruct) { | |||
Project oldProject = projectService.getNoNull(projectDto.getId()); | |||
Project project = new Project(); | |||
BeanUtil.copyProperties(oldProject, project, CopyOptions.create() | |||
@@ -1087,7 +1099,7 @@ public class ProjectLibManage { | |||
return project; | |||
} | |||
public Project saveProjectWithVersion(Project oldProject, String instanceId, Integer instType) { | |||
public Project saveProjectWithNewVersion(Project oldProject, String instanceId, Integer instType) { | |||
Project project = new Project(); | |||
Assert.notNull(oldProject, "项目不存在"); | |||
BeanUtil.copyProperties(oldProject, project, CopyOptions.create() | |||
@@ -279,6 +279,9 @@ public class ProjectDTO implements Serializable { | |||
@ApiModelProperty("建设方案文件") | |||
private String constructionPlanFile; | |||
@ApiModelProperty("建设方案盖章文件") | |||
private String constructionPlanSealFile; | |||
@ApiModelProperty("立项批复文件") | |||
private String approvedFile; | |||
@@ -269,7 +269,10 @@ public class Project implements Serializable { | |||
@ApiModelProperty("一地创新全省共享项目-是否开启 false:关闭 true:开启") | |||
private Boolean isInnovateWholeProvinceShare; | |||
@TableField(fill = FieldFill.INSERT) | |||
private LocalDateTime createOn; | |||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||
private LocalDateTime updateOn; | |||
@ApiModelProperty("流程实例编号") | |||
@@ -40,6 +40,7 @@ public enum ProjectStatus implements IStatus<Integer, String> { | |||
ON_EXPERT_REVIEW(10051, "专家评审中", 10000), | |||
EXPERT_REVIEW_FAILED(10052, "专家评审不通过", 10000), | |||
EXPERT_REVIEW_PASSED(10053, "专家评审通过", 10000), | |||
EXPERT_REVIEW_AFTER_MODIFY(10054, "修改方案后重新评审", 10000), | |||
/** | |||
* 项目复核 | |||
@@ -414,7 +414,7 @@ public class ProjectDetailVO { | |||
private List<PurchaseFullInfoVO> purchaseDetails; | |||
@ApiModelProperty("项目评审详情") | |||
private ProjectReviewResultDTO reviewDetail; | |||
private List<ProjectReviewResultDTO> reviewDetail; | |||
@ApiModelProperty("版本号str") | |||
private String versionStr; | |||