diff --git a/pmapi/pom.xml b/pmapi/pom.xml index 4cac2ab..f476b66 100644 --- a/pmapi/pom.xml +++ b/pmapi/pom.xml @@ -246,10 +246,6 @@ ${basedir}/src/lib/zwdd-sdk-java-1.2.0.jar - com.ningdatech - nd-rabbitmq-starter - - org.apache.httpcomponents httpclient diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/PrequalificationDeclaredController.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/PrequalificationDeclaredController.java index bdb2f49..b6ecd2b 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/PrequalificationDeclaredController.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/PrequalificationDeclaredController.java @@ -49,7 +49,6 @@ public class PrequalificationDeclaredController { @ApiOperation(value = "申报预审", notes = "申报预审") @PostMapping("/start") public String startTheProcess(@Validated @RequestBody DefaultDeclaredDTO dto) { - String instanceId = prequalificationDeclaredProjectManage.startTheProcess(dto); - return "提交预审 【" + instanceId + "】 成功"; + return prequalificationDeclaredProjectManage.startTheProcess(dto); } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java index 2d7b786..10426ce 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java @@ -82,7 +82,6 @@ public class ConstructionPlanManage { VUtils.isTrue(!ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode().equals(projectInfo.getStatus()) || !ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage())) .throwMessage("提交失败 该项目不是 方案待申报状态或者未立项阶段"); - // TODO 再判断 该项目是否 真实走完 预审审批 ProcessStartParamsVo params = new ProcessStartParamsVo(); params.setUser(dto.getUser()); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java index ab6f90a..9770d1b 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java @@ -114,6 +114,14 @@ public class DeclaredProjectManage { @Transactional(rollbackFor = Exception.class) public String startTheProcess(DefaultDeclaredDTO dto) { ProjectDTO projectInfo = dto.getProjectInfo(); + + //如果是重新提交的话 判断下 项目是否存在 + if(Objects.nonNull(projectInfo.getId())){ + Project oldProject = projectService.getById(projectInfo.getId()); + VUtils.isTrue(Objects.isNull(oldProject)) + .throwMessage(String.format("重新提交失败 该项目【%s】不存在",projectInfo.getId())); + } + String regionCode = projectInfo.getAreaCode(); WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) @@ -144,8 +152,8 @@ public class DeclaredProjectManage { String instanceId = processService.startProcess(model.getProcessDefId(), params); log.info("申报项目成功 【{}】", instanceId); - //保存项目 - saveProject(dto.getProjectInfo(), instanceId, regionCode); + //如果是重新提交的话 判断下 项目是否存在 + saveOrUpdateProject(dto.getProjectInfo(), instanceId, regionCode); return instanceId; } @@ -174,6 +182,11 @@ public class DeclaredProjectManage { throw new BusinessException(String.format("此 【%s】区域找不到单位流程配置", regionCode)); } + //首先要判断 项目当前状态 是不是 单位内部拒绝 + VUtils.isTrue(!ProjectStatusEnum.UNDER_INTERNAL_AUDIT_NOT_PASS.getCode().equals(projectInfo.getStatus()) || + !ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage())) + .throwMessage("提交失败 该项目不是 单位内部拒绝审核状态或者未立项阶段"); + ProcessStartParamsVo params = new ProcessStartParamsVo(); params.setUser(dto.getUser()); params.setProcessUsers(Collections.emptyMap()); @@ -221,7 +234,7 @@ public class DeclaredProjectManage { * @param projectDto * @param instanceId */ - private void saveProject(ProjectDTO projectDto, String instanceId, String regionCode) { + private void saveOrUpdateProject(ProjectDTO projectDto, String instanceId, String regionCode) { //流程启动之后 入库项目 重要业务信息 用于列表查询 展示 try { //保存项目表信息 @@ -233,7 +246,7 @@ public class DeclaredProjectManage { project.setStage(ProjectStatusEnum.NOT_APPROVED.getCode()); project.setStatus(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode()); project.setInstCode(instanceId); - projectService.save(project); + projectService.saveOrUpdate(project); //保存项目应用 if (CollUtil.isNotEmpty(projectDto.getApplicationList())) { List applications = projectDto.getApplicationList().stream().map(application -> { @@ -250,6 +263,7 @@ public class DeclaredProjectManage { 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); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/PrequalificationDeclaredProjectManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/PrequalificationDeclaredProjectManage.java index 9819482..ba26fff 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/PrequalificationDeclaredProjectManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/PrequalificationDeclaredProjectManage.java @@ -15,6 +15,7 @@ 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.ningdatech.pmapi.staging.serivice.IProjectStagingService; import com.wflow.bean.entity.WflowModels; import com.wflow.exception.BusinessException; import com.wflow.workflow.bean.vo.ProcessStartParamsVo; @@ -52,6 +53,8 @@ public class PrequalificationDeclaredProjectManage { private final IProjectInstService projectInstService; + private final IProjectStagingService projectStagingService; + /** * 提交预审 * @@ -95,8 +98,13 @@ public class PrequalificationDeclaredProjectManage { //如果是省级部门 需要联审的(申报金额大于1000万 并且是市级项目) if(ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS .getCode().equals(projectInfo.getStatus())){ - //TODO 对接外部 省级 - instanceId = DeclaredProjectContant.Instance.PROVINCE_INSTANCE_ID; + //入库暂存表 后续处理 对接外部接口 + projectInfo.setUpdateOn(LocalDateTime.now()); + if(projectStagingService.addByProject(projectInfo,"省级部门联审") + && projectService.updateById(projectInfo)){ + return "提交省级部门联审成功"; + } + return "提交省级部门联审失败"; }else if(ProjectStatusEnum.PRE_APPLYING .getCode().equals(projectInfo.getStatus())){ //如果是非省级联审的项目 直接提交 预审 @@ -115,14 +123,13 @@ public class PrequalificationDeclaredProjectManage { log.info("提交预审项目成功 【{}】", instanceId); //保存预审项目 - if(Objects.nonNull(instanceId)){ - modifyProject(projectInfo, instanceId); - } + modifyProject(projectInfo, instanceId); + }else{ throw new BusinessException("项目状态 错误 project :" + JSON.toJSONString(projectInfo)); } - return instanceId; + return "提交预审成功【" + instanceId + "】"; } /** @@ -146,6 +153,7 @@ public class PrequalificationDeclaredProjectManage { projectInst.setInstCode(instanceId); projectInst.setCreatOn(LocalDateTime.now()); projectInst.setUpdateOn(LocalDateTime.now()); + projectInst.setInstType(ProjectProcessStageEnum.PROJECT_PREQUALIFICATION_APPROVAL_PROCESS.getCode()); projectInstService.save(projectInst); } catch (Exception e) { log.error("提交预审 项目信息修改 错误 ", e); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByDeptJointManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByDeptJointManage.java new file mode 100644 index 0000000..a20f562 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByDeptJointManage.java @@ -0,0 +1,87 @@ +package com.ningdatech.pmapi.projectdeclared.manage; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ningdatech.basic.function.VUtils; +import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; +import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import com.ningdatech.pmapi.projectlib.service.IProjectInstService; +import com.ningdatech.pmapi.projectlib.service.IProjectService; +import com.wflow.bean.entity.WflowModels; +import com.wflow.exception.BusinessException; +import com.wflow.workflow.service.ProcessInstanceService; +import com.wflow.workflow.service.ProcessModelService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import java.util.Objects; + +/** + * @Classname ReviewByDeptJointManage + * @Description 部门联审 + * @Date 2023/2/17 14:48 + * @Author PoffyZhang + */ +@Component +@Slf4j +@RequiredArgsConstructor +public class ReviewByDeptJointManage { + + private final IProjectService projectService; + + private final ProcessModelService processModelService; + + private final ProcessInstanceService processService; + + private final IProjectInstService projectInstService; + + /** + * 省级部门联审 + * @param project + * @return + */ + @Transactional(rollbackFor = Exception.class) + public Boolean startTheProcess(Project project) { + VUtils.isTrue(Objects.isNull(project.getId())).throwMessage("提交失败 缺少项目ID!"); + Project projectInfo = projectService.getById(project.getId()); + VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); + String regionCode = projectInfo.getAreaCode(); + + WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) + .eq(WflowModels::getRegionCode, regionCode) + .eq(WflowModels::getProcessType, ProjectProcessStageEnum.DEPARTMENT_JOINT_APPROVAL_PROCESS.getCode()) + .last("limit 1")); + + if (Objects.isNull(model)) { + log.error("此 【{}】区域找不到 部门联审申报流程配置", regionCode); + throw new BusinessException(String.format("此 【%s】区域找不到 部门联审申报流程配置", regionCode)); + } + //要判断 项目当前状态 是不是 部门联审 + VUtils.isTrue(!ProjectStatusEnum.DEPARTMENT_JOINT_REVIEW.getCode().equals(projectInfo.getStatus()) || + !ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage())) + .throwMessage("提交失败 该项目不是 省级部门联审状态状态或者未立项阶段"); + + // 再判断 该项目是否 真实走完 预审审批 并且提取出 提交人 +// projectInstService. +// +// ProcessStartParamsVo params = new ProcessStartParamsVo(); +// params.setUser(dto.getUser()); +// params.setProcessUsers(Collections.emptyMap()); +// //放入条件判断的项目字段 +// ProjectConditionDTO conditionDto = new ProjectConditionDTO(); +// BeanUtils.copyProperties(projectInfo, conditionDto); +// dto.getFormData().putAll( +// JSON.parseObject(JSON.toJSONString(conditionDto), new TypeReference>() { +// }) +// ); +// params.setFormData(dto.getFormData()); +// String instanceId = processService.startProcess(model.getProcessDefId(), params); +// log.info("建设方案项目申报成功 【{}】", instanceId); +// +// //保存建设项目 +// modifyProject(projectInfo, instanceId, projectInfo.getConstructionPlanFile()); + + return null; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByProvincialDeptManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByProvincialDeptManage.java new file mode 100644 index 0000000..108fdf8 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByProvincialDeptManage.java @@ -0,0 +1,50 @@ +package com.ningdatech.pmapi.projectdeclared.manage; + +import com.ningdatech.basic.function.VUtils; +import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import com.ningdatech.pmapi.projectlib.service.IProjectService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import java.util.Objects; + +/** + * @Classname ReviewByProvincialDeptManage + * @Description 省级部门联审 + * @Date 2023/2/17 14:48 + * @Author PoffyZhang + */ +@Component +@Slf4j +@RequiredArgsConstructor +public class ReviewByProvincialDeptManage { + + private final IProjectService projectService; + + /** + * 省级部门联审 + * @param project + * @return + */ + @Transactional(rollbackFor = Exception.class) + public Boolean startTheProcess(Project project) { + VUtils.isTrue(Objects.isNull(project.getId())).throwMessage("提交失败 缺少项目ID!"); + Project projectInfo = projectService.getById(project.getId()); + VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); + String regionCode = projectInfo.getAreaCode(); + + //首先要判断 项目当前状态 是不是 省级部门联审 + VUtils.isTrue(!ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS.getCode().equals(projectInfo.getStatus()) || + !ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage())) + .throwMessage("提交失败 该项目不是 省级部门联审状态状态或者未立项阶段"); + // TODO 对接省级联审的接口 + Boolean sucessProvince = Boolean.FALSE; + if(sucessProvince){ + //成功了后 + } + + return Boolean.FALSE; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/ProjectInst.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/ProjectInst.java index efd785c..f56ae46 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/ProjectInst.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/ProjectInst.java @@ -34,6 +34,9 @@ public class ProjectInst implements Serializable { @ApiModelProperty("实例ID") private String instCode; + @ApiModelProperty("实例类型 1单位内部审批流程 2项目预审审批流程 3部门联合审批流程 4建设方案审批流程 5验收申报审批流程") + private Integer instType; + @ApiModelProperty("创建时间") private LocalDateTime creatOn; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/rabbitmq/config/DirectRabbitConfig.java b/pmapi/src/main/java/com/ningdatech/pmapi/rabbitmq/config/DirectRabbitConfig.java deleted file mode 100644 index 0ce2b91..0000000 --- a/pmapi/src/main/java/com/ningdatech/pmapi/rabbitmq/config/DirectRabbitConfig.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ningdatech.pmapi.rabbitmq.config; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.amqp.core.Binding; -import org.springframework.amqp.core.BindingBuilder; -import org.springframework.amqp.core.DirectExchange; -import org.springframework.amqp.core.Queue; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author zpf - * @version 1.0.0 - * @Description 创建direct类型的交换机 - * @createTime 2023年02月17日 - */ -@Slf4j -@Configuration -public class DirectRabbitConfig { - - - private static final String QUEUE = "TestDirectQueue"; - private static final String EXCHANGE = "TestDirectExchange"; - private static final String ROUTING_KEY = "TestDirectRouting"; - - /** - * 创建一个名为TestDirectQueue的队列 - * - * @return - */ - @Bean - public Queue testDirectQueue() { - // durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效 - // exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable - // autoDelete:是否自动删除,有消息者订阅本队列,然后所有消费者都解除订阅此队列,会自动删除。 - // arguments:队列携带的参数,比如设置队列的死信队列,消息的过期时间等等。 - return new Queue(QUEUE, true); - } - - /** - * 创建一个名为TestDirectExchange的Direct类型的交换机 - * - * @return - */ - @Bean - public DirectExchange testDirectExchange() { - // durable:是否持久化,默认是false,持久化交换机。 - // autoDelete:是否自动删除,交换机先有队列或者其他交换机绑定的时候,然后当该交换机没有队列或其他交换机绑定的时候,会自动删除。 - // arguments:交换机设置的参数,比如设置交换机的备用交换机(Alternate Exchange),当消息不能被路由到该交换机绑定的队列上时,会自动路由到备用交换机 - return new DirectExchange(EXCHANGE, true, false); - } - - /** - * 绑定交换机和队列 - * - * @return - */ - @Bean - public Binding bindingDirect() { - //bind队列to交换机中with路由key(routing key) - return BindingBuilder.bind(testDirectQueue()).to(testDirectExchange()).with(ROUTING_KEY); - } -} - diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/rabbitmq/config/RabbitConfig.java b/pmapi/src/main/java/com/ningdatech/pmapi/rabbitmq/config/RabbitConfig.java deleted file mode 100644 index d5a2ac1..0000000 --- a/pmapi/src/main/java/com/ningdatech/pmapi/rabbitmq/config/RabbitConfig.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.ningdatech.pmapi.rabbitmq.config; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.amqp.core.ReturnedMessage; -import org.springframework.amqp.rabbit.connection.ConnectionFactory; -import org.springframework.amqp.rabbit.connection.CorrelationData; -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Slf4j -@Configuration -public class RabbitConfig { - - @Bean - public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory) { - RabbitTemplate rabbitTemplate = new RabbitTemplate(); - rabbitTemplate.setConnectionFactory(connectionFactory); - - //设置消息投递失败的策略,有两种策略:自动删除或返回到客户端。 - //我们既然要做可靠性,当然是设置为返回到客户端(true是返回客户端,false是自动删除) - rabbitTemplate.setMandatory(true); - - rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { - @Override - public void confirm(CorrelationData correlationData, boolean ack, String cause) { - if (ack) { - log.info("ConfirmCallback 关联数据:{},投递成功,确认情况:{}", correlationData, ack); - } else { - log.info("ConfirmCallback 关联数据:{},投递失败,确认情况:{},原因:{}", correlationData, ack, cause); - } - } - }); - - rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() { - @Override - public void returnedMessage(ReturnedMessage returnedMessage) { - log.info("ReturnsCallback 消息:{},回应码:{},回应信息:{},交换机:{},路由键:{}" - , returnedMessage.getMessage(), returnedMessage.getReplyCode() - , returnedMessage.getReplyText(), returnedMessage.getExchange() - , returnedMessage.getRoutingKey()); - } - }); - - return rabbitTemplate; - } -} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/rabbitmq/controller/TestController.java b/pmapi/src/main/java/com/ningdatech/pmapi/rabbitmq/controller/TestController.java deleted file mode 100644 index aeecc81..0000000 --- a/pmapi/src/main/java/com/ningdatech/pmapi/rabbitmq/controller/TestController.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.ningdatech.pmapi.rabbitmq.controller; - -import com.alibaba.fastjson.JSON; -import com.ningdatech.pmapi.user.entity.UserInfo; -import org.springframework.amqp.rabbit.connection.CorrelationData; -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.UUID; - -/** - * @author zpf - * @version 1.0.0 - * @Description - * @createTime 2023年02月17日 - */ -@RestController -public class TestController { - - @Autowired - RabbitTemplate rabbitTemplate; - - - @GetMapping("/test") - public String test() { - return "producer ok"; - } - - @GetMapping("/push") - public String push() { - for (int i = 1; i <= 5; i++) { - //这个参数是用来做消息的唯一标识 - //发布消息时使用,存储在消息的headers中 - UserInfo user = new UserInfo(); - user.setId(1L); - user.setRealName("汪涵"); - // 关联的数据,可以用在消息投递失败的时候,作为一个线索,比如我把当前用户的id放进去,如果user消息投递失败 - // 我后面可以根据id再找到user,再次投递数据 - CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString().concat("-") + i); - if (i == 2) { - //故意把交换机写错,演示 confirmCallback - rabbitTemplate.convertAndSend("TestDirectExchange_111", "TestDirectRouting", - JSON.toJSONString(user), correlationData); - } else if (i == 3) { - //故意把路由键写错,演示 returnCallback - rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting_111", - JSON.toJSONString(user), correlationData); - } else { - //正常发送 - rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", - JSON.toJSONString(user), correlationData); - } - } - return "producer push ok"; - } -} - diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/ProjectStatusFlowTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/ProjectStatusFlowTask.java new file mode 100644 index 0000000..db7c711 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/ProjectStatusFlowTask.java @@ -0,0 +1,93 @@ +package com.ningdatech.pmapi.scheduler.task; + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSON; +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.staging.contants.StagingContant; +import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; +import com.ningdatech.pmapi.staging.serivice.IProjectStagingService; +import com.ningdatech.pmapi.staging.utils.ProjectStatusFlowMapUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +/** + * @Classname ProjectStatusFlowTask + * @Description + * @Date 2023/2/20 10:12 + * @Author PoffyZhang + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class ProjectStatusFlowTask { + + private final IProjectStagingService projectStagingService; + + private final IProjectService projectService; + + private final ProjectStatusFlowMapUtil projectStatusFlowMapUtil; + + @Scheduled(cron = "0 */1 * * * ?") + public void statusFlow() throws UnknownHostException { + //测试暂时用自己电脑HOST + if (TaskContant.Host.HOST_ZPF.equals(InetAddress.getLocalHost().getHostName())) { + //1. 定时取 项目暂存表的数据 去进行状态继续流转 + List stagingList = projectStagingService.list(Wrappers.lambdaQuery(ProjectStaging.class) + .eq(ProjectStaging::getDead,Boolean.FALSE) + .ge(ProjectStaging::getNextTime, LocalDateTime.now()) + .le(ProjectStaging::getRetryTimes, StagingContant.Retry.MAX_RETRY_TIMES) + .orderByAsc(ProjectStaging::getProjectId)); + + log.info("需要状态流转的项目 size:{} :{}",stagingList.size(), JSON.toJSONString(stagingList)); + if(CollUtil.isEmpty(stagingList)){ + log.info("没有需要状态流转的项目!"); + return; + } + + //遍历 + for(ProjectStaging projectStaging : stagingList){ + try{ + Project project = projectService.getById(projectStaging.getProjectId()); + if(Objects.isNull(project)){ + log.info("此项目 【{}】 不存在",projectStaging.getProjectId()); + continue; + } + + //2. 用函数map 定位到 状态流转的函数 + Map> reStartProcessMap = + projectStatusFlowMapUtil.statusFlowFunctionMap; + + if(!reStartProcessMap.containsKey(project.getStatus())){ + log.info("此项目 【{}】 当前状态 【{}】,没有对应流转函数",projectStaging.getProjectId(),project.getStatus()); + continue; + } + + Function functionMap = reStartProcessMap.get(project.getStatus()); + //执行对应的函数 + if(functionMap.apply(project)){ + //执行成功了 删除暂存的数据 + projectStagingService.removeById(projectStaging); + } + }catch (Exception e){ + log.error("项目流转 异常 projectId:【" + projectStaging.getProjectId() + "】 异常内容:" + e); + }finally { + //增加重试的次数 和下次扫描时间 + projectStagingService.addRetryTimes(projectStaging); + } + } + } + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/staging/contants/StagingContant.java b/pmapi/src/main/java/com/ningdatech/pmapi/staging/contants/StagingContant.java new file mode 100644 index 0000000..173e2c8 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/staging/contants/StagingContant.java @@ -0,0 +1,12 @@ +package com.ningdatech.pmapi.staging.contants; + +/** + * 项目暂存 静态配置 + */ +public interface StagingContant { + + class Retry { + public static final Integer MAX_RETRY_TIMES = 10; + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/staging/mapper/ProjectStagingMapper.java b/pmapi/src/main/java/com/ningdatech/pmapi/staging/mapper/ProjectStagingMapper.java new file mode 100644 index 0000000..5508314 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/staging/mapper/ProjectStagingMapper.java @@ -0,0 +1,13 @@ +package com.ningdatech.pmapi.staging.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; + +public interface ProjectStagingMapper extends BaseMapper { + + Boolean addRetryTimes(@Param("id") Long id, @Param("retryTimes") Integer retryTimes, + @Param("nextRetryTime") LocalDateTime nextRetryTime,@Param("dead") Boolean dead); +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/staging/mapper/ProjectStagingMapper.xml b/pmapi/src/main/java/com/ningdatech/pmapi/staging/mapper/ProjectStagingMapper.xml new file mode 100644 index 0000000..15d0557 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/staging/mapper/ProjectStagingMapper.xml @@ -0,0 +1,12 @@ + + + + + + update nd_project_staging + set retry_times = #{retryTimes}, + next_time = #{nextRetryTime}, + dead = #{dead} + where id = #{id} and retry_times = #{retryTimes - 1} + + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/staging/model/entity/ProjectStaging.java b/pmapi/src/main/java/com/ningdatech/pmapi/staging/model/entity/ProjectStaging.java new file mode 100644 index 0000000..583b57e --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/staging/model/entity/ProjectStaging.java @@ -0,0 +1,69 @@ +package com.ningdatech.pmapi.staging.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * @Classname ProjectStaging + * @Description + * @Date 2023/2/20 9:40 + * @Author PoffyZhang + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@TableName("nd_project_staging") +@ApiModel(value = "ProjectStaging", description = "项目暂存表 扫描进行 状态继续流转 做解耦用") +public class ProjectStaging implements Serializable { + + @ApiModelProperty("主键") + @TableId(type = IdType.AUTO) + private Long id; + + @ApiModelProperty("项目ID") + private Long projectId; + + @ApiModelProperty("项目名称") + private String projectName; + + @ApiModelProperty("实例code") + private String instCode; + + @ApiModelProperty("流程状态") + private Integer processStatus; + + @ApiModelProperty("项目阶段") + private Integer stage; + + @ApiModelProperty("项目状态") + private Integer status; + + @ApiModelProperty("备注") + private String remark; + + @ApiModelProperty("重试次数") + private Integer retryTimes; + + @ApiModelProperty("是否死信") + private Boolean dead; + + @ApiModelProperty("下次扫描时间") + private LocalDateTime nextTime; + + @ApiModelProperty("创建时间") + private LocalDateTime createOn; + + @ApiModelProperty("修改时间") + private LocalDateTime updateOn; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/staging/serivice/IProjectStagingService.java b/pmapi/src/main/java/com/ningdatech/pmapi/staging/serivice/IProjectStagingService.java new file mode 100644 index 0000000..5481a4a --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/staging/serivice/IProjectStagingService.java @@ -0,0 +1,18 @@ +package com.ningdatech.pmapi.staging.serivice; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; + +/** + * @Classname IProjectStagingService + * @Description + * @Date 2023/2/20 10:08 + * @Author PoffyZhang + */ +public interface IProjectStagingService extends IService { + + Boolean addRetryTimes(ProjectStaging projectStaging); + + public Boolean addByProject(Project project,String remark) ; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/staging/serivice/impl/ProjectStagingServiceImpl.java b/pmapi/src/main/java/com/ningdatech/pmapi/staging/serivice/impl/ProjectStagingServiceImpl.java new file mode 100644 index 0000000..cb131a7 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/staging/serivice/impl/ProjectStagingServiceImpl.java @@ -0,0 +1,77 @@ +package com.ningdatech.pmapi.staging.serivice.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import com.ningdatech.pmapi.staging.contants.StagingContant; +import com.ningdatech.pmapi.staging.mapper.ProjectStagingMapper; +import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; +import com.ningdatech.pmapi.staging.serivice.IProjectStagingService; +import com.ningdatech.pmapi.staging.utils.ProjectStatusFlowMapUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +/** + *

+ * 服务实现类 + *

+ * + * @author zpf + * @since 2023-02-18 + */ +@Service +@Slf4j +@RequiredArgsConstructor +public class ProjectStagingServiceImpl extends ServiceImpl implements IProjectStagingService { + + private final ProjectStagingMapper mapper; + + private final ProjectStatusFlowMapUtil projectStatusFlowMapUtil; + + /** + * 在某些状态节点 增加一个项目到状态暂存库 + * @param project + * @return + */ + @Override + public Boolean addByProject(Project project,String remark) { + ProjectStaging projectStaging = ProjectStaging.builder() + .projectId(project.getId()) + .projectName(project.getProjectName()) + .stage(project.getStage()) + .status(project.getStatus()) + .createOn(LocalDateTime.now()) + .updateOn(LocalDateTime.now()) + .instCode(project.getInstCode()) + .processStatus(project.getProcessStatus()) + .nextTime(LocalDateTime.now()) + .retryTimes(0) + .remark(remark) + .build(); + return this.save(projectStaging); + } + + /** + * 增加 重试次数 和下次扫描时间 + * @param projectStaging + * @return + */ + @Override + public Boolean addRetryTimes(ProjectStaging projectStaging) { + Integer retryTimes = projectStaging.getRetryTimes() + 1; + if(!projectStatusFlowMapUtil.intervalTimeMap.containsKey(retryTimes)){ + log.info("没有对应重试间隔时间 添加重试信息失败"); + return Boolean.FALSE; + } + Integer addSeconds = projectStatusFlowMapUtil.intervalTimeMap.get(retryTimes); + Boolean dead = Boolean.FALSE; + //超过重试最大次数 dead置为 true + if(retryTimes.compareTo(StagingContant.Retry.MAX_RETRY_TIMES) > 0){ + dead = Boolean.TRUE; + } + LocalDateTime nextRetryTime = LocalDateTime.now().plusSeconds(addSeconds); + return mapper.addRetryTimes(projectStaging.getId(),retryTimes,nextRetryTime,dead); + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/staging/utils/ProjectStatusFlowMapUtil.java b/pmapi/src/main/java/com/ningdatech/pmapi/staging/utils/ProjectStatusFlowMapUtil.java new file mode 100644 index 0000000..876f2d5 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/staging/utils/ProjectStatusFlowMapUtil.java @@ -0,0 +1,66 @@ +package com.ningdatech.pmapi.staging.utils; + +import com.google.common.collect.Maps; +import com.ningdatech.pmapi.projectdeclared.manage.*; +import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; +import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; +import lombok.RequiredArgsConstructor; +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 +@RequiredArgsConstructor +public class ProjectStatusFlowMapUtil { + private final ReviewByProvincialDeptManage provincialDeptManage; + + private final ReviewByDeptJointManage reviewByDeptJointManage; + + public Map> statusFlowFunctionMap = Maps.newHashMap(); + /** + * key 重试的次数 , value 是增加是描述 + */ + public Map intervalTimeMap = Maps.newHashMap(); + + /** + * 初始化业务分派逻辑,代替了if-else部分 + * key: 枚举 状态值 + * value: lambda表达式,最终会获取发起实例的函数 + */ + @PostConstruct + public void statusFlowFunctionInit(){ + //省级部门联审 + statusFlowFunctionMap.put(ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS.getCode(), + project->provincialDeptManage.startTheProcess(project)); + //部门联审 + statusFlowFunctionMap.put(ProjectStatusEnum.DEPARTMENT_JOINT_REVIEW.getCode(), + 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); + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/user/manage/UserInfoManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/user/manage/UserInfoManage.java index 31caf14..a03aa5c 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/user/manage/UserInfoManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/user/manage/UserInfoManage.java @@ -2,6 +2,7 @@ package com.ningdatech.pmapi.user.manage; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ningdatech.basic.exception.BizException; @@ -46,7 +47,8 @@ public class UserInfoManage { public PageVo list(ReqUserInfoListPO reqUserInfoListPO) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(DingEmployeeInfo.class) - .eq(DingEmployeeInfo::getMainJob, "true"); + .eq(DingEmployeeInfo::getMainJob, "true") + .eq(StringUtils.isNotBlank(reqUserInfoListPO.getOrgCode()), DingEmployeeInfo::getOrganizationCode, reqUserInfoListPO.getOrgCode()); Page page = iDingEmployeeInfoService.page(new Page<>(reqUserInfoListPO.getPageNumber(), reqUserInfoListPO.getPageSize()), wrapper); List records = page.getRecords(); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/user/model/po/ReqUserInfoListPO.java b/pmapi/src/main/java/com/ningdatech/pmapi/user/model/po/ReqUserInfoListPO.java index 9b2ff6d..d6381aa 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/user/model/po/ReqUserInfoListPO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/user/model/po/ReqUserInfoListPO.java @@ -25,6 +25,9 @@ public class ReqUserInfoListPO extends PagePo { @ApiModelProperty("所在单位(主职)") private String orgName; + @ApiModelProperty("所在单位Code(主职)") + private String orgCode; + @ApiModelProperty("所属区域") private Long regionId; diff --git a/pmapi/src/test/resources/application-dev.yml b/pmapi/src/test/resources/application-dev.yml index 616bd7f..7260845 100644 --- a/pmapi/src/test/resources/application-dev.yml +++ b/pmapi/src/test/resources/application-dev.yml @@ -87,17 +87,6 @@ spring: wall: config: multi-statement-allow: true - # rabbitmq 配置信息 - rabbitmq: - host: 110.40.194.60 - port: 5672 - username: admin - password: admin - #1、确保消息从发送端到服务端投递可靠(分为以下两个步骤) - #1.1、确认消息已发送到交换机(Exchange) 可以把publisher-confirms: true 替换为 publisher-confirm-type: correlate - publisher-confirm-type: correlated - #1.2、确认消息从交换机中到队列中 - publisher-returns: true mybatis-plus: configuration: diff --git a/pom.xml b/pom.xml index e6d82f5..b46ca5d 100644 --- a/pom.xml +++ b/pom.xml @@ -150,11 +150,6 @@ 1.0.0 - com.ningdatech - nd-rabbitmq-starter - 1.0.0 - - joda-time joda-time 2.10.6