@@ -8,6 +8,7 @@ package com.ningdatech.pmapi.common.constant; | |||
public class StateMachineConst { | |||
public static final String PROJECT_DECLARE = "projectDeclare"; | |||
public static final String APPLICATION_DECLARE = "applicationDeclare"; | |||
public static final String LI_SHUI_CITY_AREA_CODE = "331100"; | |||
} |
@@ -1,15 +1,22 @@ | |||
package com.ningdatech.pmapi.common.statemachine.action; | |||
import cn.hutool.core.collection.CollUtil; | |||
import com.ningdatech.pmapi.common.constant.ProjectDeclareConst; | |||
import com.ningdatech.pmapi.common.constant.StateMachineConst; | |||
import com.ningdatech.pmapi.common.enumeration.CommonEnum; | |||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||
import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | |||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.statemachine.StateContext; | |||
import org.springframework.statemachine.action.Action; | |||
import java.util.List; | |||
import static com.ningdatech.pmapi.common.constant.StateMachineConst.APPLICATION_DECLARE; | |||
/** | |||
* 项目申报状态机选择分支action类 | |||
* | |||
@@ -32,11 +39,31 @@ public class ProjectDeclareChoiceAction implements Action<ProjectStatusEnum, Pro | |||
case PREQUALIFICATION_WITHDRAW_CHOICE: | |||
preWithDrawChoice(stateContext); | |||
break; | |||
case APPROVED_AFTER_CHOICE: | |||
approvedAfterChoice(stateContext); | |||
break; | |||
default: | |||
throw new IllegalStateException("Unexpected value: " + projectStatusEnum); | |||
} | |||
} | |||
private void approvedAfterChoice(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) { | |||
List<ProjectApplication> projectApplications = stateContext.getMessage().getHeaders().get(APPLICATION_DECLARE, List.class); | |||
Project project = stateContext.getMessage().getHeaders().get(PROJECT_DECLARE, Project.class); | |||
log.info("立项批复之后,项目的状态为:{}" + project.getStatus()); | |||
// 判断 是否有初次创建的应用 | |||
if (CollUtil.isEmpty(projectApplications)){ | |||
project.setStatus(ProjectStatusEnum.TO_BE_PURCHASED.getCode()); | |||
} | |||
projectApplications.stream().forEach(app -> { | |||
Integer isFirst = app.getIsFirst(); | |||
if(isFirst.equals(CommonEnum.YES.getCode())){ | |||
project.setStatus(ProjectStatusEnum.TO_BE_APP_REGISTER.getCode()); | |||
return; | |||
} | |||
}); | |||
} | |||
private void preDeclareChoice(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) { | |||
Project project = stateContext.getMessage().getHeaders().get(PROJECT_DECLARE, Project.class); | |||
log.info("预审申报事件之前,项目的状态为:{}"+project.getStatus()); | |||
@@ -190,10 +190,18 @@ public class ProjectDeclareSCAction { | |||
} | |||
@OnTransition(source = "TO_BE_APPROVED", target = "TO_BE_PURCHASED") | |||
@OnTransition(source = "TO_BE_APPROVED", target = "APPROVED_AFTER_CHOICE") | |||
public void PROJECT_APPROVAL(Message<ProjectStatusChangeEvent> message) { | |||
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | |||
// 待立项批复批复后,项目一级状态变更为已立项 | |||
project.setStage(ProjectStatusEnum.NOT_APPROVED.getCode()); | |||
project.setStatus(ProjectStatusEnum.APPROVED_AFTER_CHOICE.getCode()); | |||
} | |||
@OnTransition(source = "TO_BE_APP_REGISTER", target = "TO_BE_PURCHASED") | |||
public void REGISTER_APP(Message<ProjectStatusChangeEvent> message) { | |||
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE); | |||
// 待立项批复批复后,项目一级状态变更为已立项 | |||
project.setStage(ProjectStatusEnum.PROJECT_APPROVED.getCode()); | |||
project.setStatus(ProjectStatusEnum.TO_BE_PURCHASED.getCode()); | |||
} | |||
@@ -69,6 +69,7 @@ public class ProjectDeclareStateMachineSCBuilder implements ProjectDeclareStateM | |||
.initial(ProjectStatusEnum.UNDER_INTERNAL_AUDIT) | |||
.choice(ProjectStatusEnum.PENDING_PREQUALIFICATION_CHOICE) | |||
.choice(ProjectStatusEnum.PREQUALIFICATION_WITHDRAW_CHOICE) | |||
.choice(ProjectStatusEnum.APPROVED_AFTER_CHOICE) | |||
.states(EnumSet.allOf(ProjectStatusEnum.class)); | |||
builder.configureTransitions() | |||
@@ -209,8 +210,17 @@ public class ProjectDeclareStateMachineSCBuilder implements ProjectDeclareStateM | |||
// 待立项批复批复,从待立项批复到待采购 | |||
.withExternal() | |||
.source(ProjectStatusEnum.TO_BE_APPROVED) | |||
.target(ProjectStatusEnum.TO_BE_PURCHASED) | |||
.target(ProjectStatusEnum.APPROVED_AFTER_CHOICE) | |||
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and() | |||
.withChoice() | |||
.source(ProjectStatusEnum.APPROVED_AFTER_CHOICE) | |||
.first(ProjectStatusEnum.TO_BE_APP_REGISTER,projectDeclareGuardFactory.new ApprovedAfterChoiceGuard(),new ProjectDeclareChoiceAction()) | |||
.last(ProjectStatusEnum.TO_BE_PURCHASED,new ProjectDeclareChoiceAction()).and() | |||
//待所有应用都注册 并且 绑定了关系后 再进入下一状态 待采购 | |||
.withExternal() | |||
.source(ProjectStatusEnum.TO_BE_APP_REGISTER) | |||
.target(ProjectStatusEnum.TO_BE_PURCHASED) | |||
.event(ProjectStatusChangeEvent.REGISTER_APP).and() | |||
// 待采购采购备案,从待采购到建设中 | |||
.withExternal() | |||
.source(ProjectStatusEnum.TO_BE_PURCHASED) | |||
@@ -105,6 +105,11 @@ public enum ProjectStatusChangeEvent { | |||
* 立项批复(项目状态变为:已立项-待采购) | |||
*/ | |||
PROJECT_APPROVAL(ProjectStatusEnum.TO_BE_APPROVED.getCode(), null, null), | |||
/** | |||
* 注册应用 | |||
*/ | |||
REGISTER_APP(ProjectStatusEnum.TO_BE_APP_REGISTER.getCode(), null, null), | |||
/** | |||
* 采购备案(项目状态变为:建设中) | |||
*/ | |||
@@ -1,14 +1,21 @@ | |||
package com.ningdatech.pmapi.common.statemachine.factory; | |||
import cn.hutool.core.collection.CollUtil; | |||
import com.ningdatech.pmapi.common.constant.ProjectDeclareConst; | |||
import com.ningdatech.pmapi.common.constant.StateMachineConst; | |||
import com.ningdatech.pmapi.common.enumeration.CommonEnum; | |||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||
import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | |||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | |||
import org.springframework.statemachine.StateContext; | |||
import org.springframework.statemachine.guard.Guard; | |||
import java.util.List; | |||
import static com.ningdatech.pmapi.common.constant.StateMachineConst.APPLICATION_DECLARE; | |||
/** | |||
* 项目申报状态机guard集合类 | |||
* | |||
@@ -31,4 +38,23 @@ public class ProjectDeclareGuardFactory { | |||
return false; | |||
} | |||
} | |||
public class ApprovedAfterChoiceGuard implements Guard<ProjectStatusEnum, ProjectStatusChangeEvent> { | |||
@Override | |||
public boolean evaluate(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> context) { | |||
List<ProjectApplication> projectApplications = context.getMessage().getHeaders().get(APPLICATION_DECLARE, List.class); | |||
final Boolean[] res = {Boolean.FALSE}; | |||
// 判断 是否有初次创建的应用 | |||
if (CollUtil.isEmpty(projectApplications)){ | |||
return res[0]; | |||
} | |||
projectApplications.stream().forEach(app -> { | |||
Integer isFirst = app.getIsFirst(); | |||
if(isFirst.equals(CommonEnum.YES.getCode())){ | |||
res[0] = Boolean.TRUE; | |||
} | |||
}); | |||
return res[0]; | |||
} | |||
} | |||
} |
@@ -9,9 +9,11 @@ import com.ningdatech.pmapi.common.statemachine.builder.ProjectDeclareStateMachi | |||
import com.ningdatech.pmapi.common.statemachine.contants.RegionContant; | |||
import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent; | |||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | |||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectStatusChange; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.ningdatech.pmapi.projectlib.service.INdProjectStatusChangeService; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | |||
import com.wflow.exception.BusinessException; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
@@ -39,8 +41,12 @@ public class StateMachineUtils { | |||
private static final String PROJECT_DECLARE = StateMachineConst.PROJECT_DECLARE; | |||
private static final String APPLICATION_DECLARE = StateMachineConst.APPLICATION_DECLARE; | |||
private final INdProjectStatusChangeService projectStatusChangeService; | |||
private final IProjectApplicationService projectApplicationService; | |||
//通过审核 | |||
public void pass(Project project) { | |||
try{ | |||
@@ -82,7 +88,10 @@ public class StateMachineUtils { | |||
VUtils.isTrue(Objects.isNull(builder)).throwMessage("状态机初始化失败!"); | |||
//获取TO状态机 | |||
StateMachine<ProjectStatusEnum, ProjectStatusChangeEvent> stateMachine = builder.build(); | |||
Message message = MessageBuilder.withPayload(event).setHeader(PROJECT_DECLARE, project).build(); | |||
Message message = MessageBuilder.withPayload(event) | |||
.setHeader(PROJECT_DECLARE, project) | |||
.setHeader(APPLICATION_DECLARE,projectApplicationService.getApplicationsByProject(project)) | |||
.build(); | |||
//初始化状态机 | |||
StateMachinePersister projectDeclareStateMachinePersister = builder.getProjectPersister(); | |||
projectDeclareStateMachinePersister.restore(stateMachine, project); | |||
@@ -18,7 +18,7 @@ import java.security.NoSuchAlgorithmException; | |||
* @Author PoffyZhang | |||
*/ | |||
@RestController | |||
@RequestMapping("/api/v1/app") | |||
@RequestMapping("/api/v1/irs/app") | |||
@AllArgsConstructor | |||
@Slf4j | |||
@Valid | |||
@@ -1,8 +1,14 @@ | |||
package com.ningdatech.pmapi.projectlib.controller; | |||
import com.ningdatech.basic.model.PageVo; | |||
import com.ningdatech.log.annotation.WebLog; | |||
import com.ningdatech.pmapi.projectlib.manage.ApplicationManage; | |||
import com.ningdatech.pmapi.projectlib.model.dto.ApplicationAppCodeSaveDTO; | |||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | |||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | |||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
import io.swagger.annotations.Api; | |||
import io.swagger.annotations.ApiOperation; | |||
import lombok.RequiredArgsConstructor; | |||
@@ -38,4 +44,9 @@ public class ProjectApplicationController { | |||
return applicationManage.saveAppCode(dto); | |||
} | |||
@GetMapping("/to-register-app-project-list") | |||
@ApiOperation("待应用预注册的项目应用列表") | |||
public PageVo<ProjectDetailVO> toRegisterAppProjectLibList(ProjectListReq req) { | |||
return applicationManage.toRegisterAppProjectLibList(req); | |||
} | |||
} |
@@ -45,6 +45,8 @@ public enum ProjectStatusEnum { | |||
PLAN_TO_BE_DECLARED(10016, "方案待申报"), | |||
PENDING_PREQUALIFICATION_CHOICE(10017, "待预审选择态"), | |||
PREQUALIFICATION_WITHDRAW_CHOICE(10019, "预审中撤回选择态"), | |||
APPROVED_AFTER_CHOICE(10020, "立项批复后选择态"), | |||
TO_BE_APP_REGISTER(10021, "待应用注册"), | |||
/** | |||
* 项目阶段:已立项 | |||
*/ | |||
@@ -1,16 +1,27 @@ | |||
package com.ningdatech.pmapi.projectlib.manage; | |||
import cn.hutool.core.bean.BeanUtil; | |||
import cn.hutool.core.collection.CollUtil; | |||
import com.alibaba.fastjson.JSON; | |||
import com.alibaba.fastjson.JSONArray; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||
import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.basic.function.VUtils; | |||
import com.ningdatech.basic.model.ApiResponse; | |||
import com.ningdatech.basic.model.PageVo; | |||
import com.ningdatech.pmapi.common.util.HmacAuthUtil; | |||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||
import com.ningdatech.pmapi.projectlib.model.dto.ApplicationAppCodeSaveDTO; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | |||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | |||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectApplicationVO; | |||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
@@ -22,8 +33,11 @@ import org.springframework.util.MultiValueMap; | |||
import org.springframework.web.client.RestTemplate; | |||
import java.time.LocalDateTime; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Objects; | |||
import java.util.stream.Collectors; | |||
/** | |||
* <p> | |||
@@ -49,6 +63,8 @@ public class ApplicationManage { | |||
private final IProjectApplicationService applicationService; | |||
private final IProjectService projectService; | |||
/** | |||
* 保存 appCode | |||
* @param dto | |||
@@ -113,4 +129,48 @@ public class ApplicationManage { | |||
} | |||
throw new BizException("获取报告失败!"); | |||
} | |||
/** | |||
* 查询 待注册的 | |||
* @param req | |||
* @return | |||
*/ | |||
public PageVo<ProjectDetailVO> toRegisterAppProjectLibList(ProjectListReq req) { | |||
UserInfoDetails user = LoginUserUtil.loginUserDetail(); | |||
//建设单位 就是当前人的单位 | |||
String orgCode = user.getEmpPosUnitCode(); | |||
Page<Project> page = req.page(); | |||
projectService.page(page,Wrappers.lambdaQuery(Project.class) | |||
.eq(Project::getStage, ProjectStatusEnum.NOT_APPROVED.getCode()) | |||
.eq(Project::getStatus, ProjectStatusEnum.TO_BE_APP_REGISTER.getCode()) | |||
.eq(Project::getBuildOrgCode,orgCode)); | |||
if(0L == page.getTotal()){ | |||
return PageVo.empty(); | |||
} | |||
List<Long> projectIds = page.getRecords().stream().map(Project::getId).collect(Collectors.toList()); | |||
//要去查询应用 | |||
List<ProjectApplication> apps = applicationService.list(Wrappers.lambdaQuery(ProjectApplication.class) | |||
.in(ProjectApplication::getProjectId, projectIds)); | |||
Map<Long, List<ProjectApplication>> appMap = apps.stream().collect(Collectors.groupingBy(ProjectApplication::getProjectId)); | |||
List<ProjectDetailVO> res = page.getRecords().stream().map(p -> { | |||
ProjectDetailVO vo = BeanUtil.copyProperties(p,ProjectDetailVO.class); | |||
if(appMap.containsKey(p.getId())){ | |||
List<ProjectApplication> projectApplications = appMap.get(p.getId()); | |||
vo.setProjectApplications(convert(projectApplications)); | |||
} | |||
return vo; | |||
}).collect(Collectors.toList()); | |||
return PageVo.of(res,page.getTotal()); | |||
} | |||
private List<ProjectApplicationVO> convert(List<ProjectApplication> projectApplications) { | |||
if(CollUtil.isNotEmpty(projectApplications)){ | |||
return projectApplications.stream() | |||
.map(a -> BeanUtil.copyProperties(a,ProjectApplicationVO.class)) | |||
.collect(Collectors.toList()); | |||
} | |||
return Collections.emptyList(); | |||
} | |||
} |
@@ -1,8 +1,11 @@ | |||
package com.ningdatech.pmapi.projectlib.service; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | |||
import com.baomidou.mybatisplus.extension.service.IService; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* 服务类 | |||
@@ -13,4 +16,5 @@ import com.baomidou.mybatisplus.extension.service.IService; | |||
*/ | |||
public interface IProjectApplicationService extends IService<ProjectApplication> { | |||
List<ProjectApplication> getApplicationsByProject(Project project); | |||
} |
@@ -1,11 +1,15 @@ | |||
package com.ningdatech.pmapi.projectlib.service.impl; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication; | |||
import com.ningdatech.pmapi.projectlib.mapper.ProjectApplicationMapper; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | |||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||
import org.springframework.stereotype.Service; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* 服务实现类 | |||
@@ -17,4 +21,11 @@ import org.springframework.stereotype.Service; | |||
@Service | |||
public class ProjectApplicationServiceImpl extends ServiceImpl<ProjectApplicationMapper, ProjectApplication> implements IProjectApplicationService { | |||
@Override | |||
public List<ProjectApplication> getApplicationsByProject(Project project) { | |||
Long projectId = project.getId(); | |||
List<ProjectApplication> apps = this.list(Wrappers.lambdaQuery(ProjectApplication.class) | |||
.eq(ProjectApplication::getProjectId, projectId)); | |||
return apps; | |||
} | |||
} |