From 55e52651525a80f4a7390ae07cbff84017a8f3a3 Mon Sep 17 00:00:00 2001 From: hhyykk Date: Sun, 7 Jul 2024 16:00:38 +0800 Subject: [PATCH] =?UTF-8?q?[feat]=20=E6=96=B0=E5=A2=9E=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E6=B5=81=E7=A8=8B=E8=A1=A8=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/pms/enums/DictTypeConstants.java | 7 ++++ .../pms/enums/EntrustMethodConstants.java | 14 +++++++ .../admin/project/ProjectController.java | 3 +- .../admin/project/vo/ProjectRespDetailVO.java | 4 +- .../admin/project/vo/ProjectRespVO.java | 6 +++ .../admin/project/vo/ProjectSaveReqVO.java | 16 ++++---- .../pms/dal/dataobject/project/ProjectDO.java | 2 +- .../pms/service/project/ProjectService.java | 13 ++++-- .../service/project/ProjectServiceImpl.java | 40 ++++++++++++++++--- .../listener/ProjectInitStatusListener.java | 30 ++++++++++++++ .../project/ProjectServiceImplTest.java | 11 +---- 11 files changed, 116 insertions(+), 30 deletions(-) create mode 100644 yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/EntrustMethodConstants.java create mode 100644 yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/listener/ProjectInitStatusListener.java diff --git a/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/DictTypeConstants.java b/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/DictTypeConstants.java index 1af9083e4..25ab8a4f0 100644 --- a/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/DictTypeConstants.java +++ b/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/DictTypeConstants.java @@ -6,9 +6,16 @@ package cn.iocoder.yudao.module.pms.enums; * @date 2024/7/3 */ public interface DictTypeConstants { + + // ***** 字典名称 ****** String PROJECT_TYPE = "project_type"; // 项目类型 String ENTRUST_METHOD = "entrust_method"; // 委托方式 String INFRA_BOOLEAN_STRING = "infra_boolean_string"; // 布尔 String PROCESS_STATUS = "process_status"; // 流程状态 String POSSIBILITY_OF_LANDING = "possibility_of_landing"; // 可能性 + String BPM_PROCESS_INSTANCE_STATUS = "bpm_process_instance_status"; // 流程实例状态 + + + + } diff --git a/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/EntrustMethodConstants.java b/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/EntrustMethodConstants.java new file mode 100644 index 000000000..8cf2feaac --- /dev/null +++ b/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/EntrustMethodConstants.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.pms.enums; + +/** + * @author hhyykk + * @description 委托方式枚举 + * @date 2024/7/6 + */ +public interface EntrustMethodConstants { + + // **** 字典值 ****** + String ENTRUST_PUBLIC_BIDDING = "public_bidding"; // 公开招标 + String ENTRUST_DIRECT_DELEGATION = "public_direct_delegation"; // 直接委托 + String ENTRUST_INVITED_BIDDING = "invited_bidding"; // 邀请招标 +} diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/ProjectController.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/ProjectController.java index abbde2f73..37336aba7 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/ProjectController.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/ProjectController.java @@ -25,6 +25,7 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import cn.iocoder.yudao.module.pms.controller.admin.project.vo.*; import cn.iocoder.yudao.module.pms.dal.dataobject.project.ProjectDO; @@ -43,7 +44,7 @@ public class ProjectController { @Operation(summary = "创建项目基本信息") @PreAuthorize("@ss.hasPermission('pms:project:create')") public CommonResult createProject(@Valid @RequestBody ProjectSaveReqVO createReqVO) { - return success(projectService.createProject(createReqVO)); + return success(projectService.createProject(getLoginUserId(),createReqVO)); } @PutMapping("/update") diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectRespDetailVO.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectRespDetailVO.java index 1a0f1f3cc..84b85e85e 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectRespDetailVO.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectRespDetailVO.java @@ -73,8 +73,8 @@ public class ProjectRespDetailVO { private String reason; @Schema(description = "审批状态", example = "doing") - @DictFormat(DictTypeConstants.PROCESS_STATUS) - private String processStatus; + @DictFormat(DictTypeConstants.BPM_PROCESS_INSTANCE_STATUS) + private Integer processStatus; @Schema(description = "状态", example = "doing") private String status; diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectRespVO.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectRespVO.java index ca501f133..87d512610 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectRespVO.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectRespVO.java @@ -52,4 +52,10 @@ public class ProjectRespVO { @Schema(description = "客户公司", example = "26238") @ExcelProperty("客户公司") private String customerCompanyName; + + @Schema(description = "流程实体id", example = "26238") + private String processInstanceId; + + @Schema(description = "委托方式", example = "public_bidding") + private String entrustMethod; } \ No newline at end of file diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectSaveReqVO.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectSaveReqVO.java index 90be02067..951ed3ed1 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectSaveReqVO.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/project/vo/ProjectSaveReqVO.java @@ -21,7 +21,7 @@ public class ProjectSaveReqVO { @Schema(description = "项目编号") private String code; - @Schema(description = "客户联系人") + @Schema(description = "客户联系人", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三") private String customerUser; @Schema(description = "出图公司", requiredMode = Schema.RequiredMode.REQUIRED) @@ -51,19 +51,19 @@ public class ProjectSaveReqVO { private String reason; @Schema(description = "审批状态", example = "2") - private String processStatus; + private Integer processStatus; - @Schema(description = "跟踪编号") + @Schema(description = "跟踪编号", requiredMode = Schema.RequiredMode.REQUIRED) private String trackingCode; - @Schema(description = "类型", example = "1") + @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private String type; @Schema(description = "客户公司id", requiredMode = Schema.RequiredMode.REQUIRED, example = "12216") @NotNull(message = "客户公司id不能为空") private Long customerCompanyId; - @Schema(description = "项目经理id", example = "26238") + @Schema(description = "项目经理id", requiredMode = Schema.RequiredMode.REQUIRED, example = "26238") private Long projectManagerId; @Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED) @@ -82,17 +82,17 @@ public class ProjectSaveReqVO { @Schema(description = "中标附件", example = "https://www.iocoder.cn") private List winFileUrl; - @Schema(description = "预计合同金额") + @Schema(description = "预计合同金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") private String contractAmount; @Schema(description = "客户电话", requiredMode = Schema.RequiredMode.REQUIRED) @NotEmpty(message = "客户电话不能为空") private String customerPhone; - @Schema(description = "省份id", example = "25195") + @Schema(description = "省份id", requiredMode = Schema.RequiredMode.REQUIRED, example = "25195") private Long provinceId; - @Schema(description = "城市id", example = "23899") + @Schema(description = "城市id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23899") private Long cityId; } \ No newline at end of file diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/project/ProjectDO.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/project/ProjectDO.java index 6c9f6f41e..45d040d0d 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/project/ProjectDO.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/project/ProjectDO.java @@ -97,7 +97,7 @@ public class ProjectDO extends BaseDO { * * 枚举 {@link DictTypeConstants} */ - private String processStatus; + private Integer processStatus; /** * 状态 */ diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/ProjectService.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/ProjectService.java index 4a4416b07..ba0533c17 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/ProjectService.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/ProjectService.java @@ -1,13 +1,10 @@ package cn.iocoder.yudao.module.pms.service.project; -import java.util.*; - import cn.iocoder.yudao.module.pms.dal.dataobject.project.ProjectDetailDO; import jakarta.validation.*; import cn.iocoder.yudao.module.pms.controller.admin.project.vo.*; import cn.iocoder.yudao.module.pms.dal.dataobject.project.ProjectDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; /** * 项目基本信息 Service 接口 @@ -19,10 +16,11 @@ public interface ProjectService { /** * 创建项目基本信息 * + * @param loginUserId 登录用户id * @param createReqVO 创建信息 * @return 编号 */ - Long createProject(@Valid ProjectSaveReqVO createReqVO); + Long createProject(Long loginUserId, @Valid ProjectSaveReqVO createReqVO); /** * 更新项目基本信息 @@ -68,4 +66,11 @@ public interface ProjectService { * @return 基本信息 */ ProjectDetailDO getProjectDetail(Long id); + + /** + * 更新项目立项状态 + * @param id 编号 + * @param status 结果 + */ + void updateProjectStatus(Long id, Integer status); } \ No newline at end of file diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/ProjectServiceImpl.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/ProjectServiceImpl.java index 32613e1b5..1c1232812 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/ProjectServiceImpl.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/ProjectServiceImpl.java @@ -1,17 +1,17 @@ package cn.iocoder.yudao.module.pms.service.project; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; +import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.pms.dal.dataobject.project.ProjectDetailDO; +import cn.iocoder.yudao.module.pms.enums.EntrustMethodConstants; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; import org.springframework.validation.annotation.Validated; -import org.springframework.transaction.annotation.Transactional; -import java.util.*; import cn.iocoder.yudao.module.pms.controller.admin.project.vo.*; import cn.iocoder.yudao.module.pms.dal.dataobject.project.ProjectDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pms.dal.mysql.project.ProjectMapper; @@ -28,15 +28,38 @@ import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstants.*; @Validated public class ProjectServiceImpl implements ProjectService { + /** + * 项目立项审批流程定义 + */ + public static final String PROCESS_KEY = "pms_project_init"; + @Resource private ProjectMapper projectMapper; + @Resource + private BpmProcessInstanceApi processInstanceApi; @Override - public Long createProject(ProjectSaveReqVO createReqVO) { + public Long createProject(Long loginUserId, ProjectSaveReqVO createReqVO) { + // 非公开招标或者邀请招标的无需审批 + if (!EntrustMethodConstants.ENTRUST_PUBLIC_BIDDING.equals(createReqVO.getEntrustMethod()) && + !EntrustMethodConstants.ENTRUST_INVITED_BIDDING.equals(createReqVO.getEntrustMethod())) { + createReqVO.setProcessStatus(2); //审批通过 + } // 插入 ProjectDO project = BeanUtils.toBean(createReqVO, ProjectDO.class); projectMapper.insert(project); - // todo 启动流程 + // 启动流程 + if (createReqVO.getId() == null) { + if (EntrustMethodConstants.ENTRUST_PUBLIC_BIDDING.equals(project.getEntrustMethod()) || + EntrustMethodConstants.ENTRUST_INVITED_BIDDING.equals(project.getEntrustMethod())) { + // 公开中标或邀请招标需要走流程 + String processInstanceId = processInstanceApi.createProcessInstance(loginUserId, + new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY) + .setBusinessKey(String.valueOf(project.getId()))); + // 写入工作流编号 + projectMapper.updateById(new ProjectDO().setId(project.getId()).setProcessInstanceId(processInstanceId)); + } + } // 返回 return project.getId(); } @@ -95,4 +118,11 @@ public class ProjectServiceImpl implements ProjectService { return dto; } + @Override + public void updateProjectStatus(Long id, Integer status) { + // 校验存在 + validateProjectExists(id); + projectMapper.updateById(new ProjectDO().setId(id).setProcessStatus(status)); + } + } \ No newline at end of file diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/listener/ProjectInitStatusListener.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/listener/ProjectInitStatusListener.java new file mode 100644 index 000000000..a76912714 --- /dev/null +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/project/listener/ProjectInitStatusListener.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.pms.service.project.listener; + +import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent; +import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEventListener; +import cn.iocoder.yudao.module.pms.service.project.ProjectService; +import cn.iocoder.yudao.module.pms.service.project.ProjectServiceImpl; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +/** + * @author hhyykk + * @description 项目立项状态监听器 + * @date 2024/7/6 + */ +@Component +public class ProjectInitStatusListener extends BpmProcessInstanceStatusEventListener { + + @Resource + private ProjectService projectService; + + @Override + protected String getProcessDefinitionKey() { + return ProjectServiceImpl.PROCESS_KEY; + } + + @Override + protected void onEvent(BpmProcessInstanceStatusEvent event) { + projectService.updateProjectStatus(Long.parseLong(event.getBusinessKey()), event.getStatus()); + } +} diff --git a/yudao-module-pms/yudao-module-pms-biz/src/test/java/cn/iocoder/yudao/module/pms/service/project/ProjectServiceImplTest.java b/yudao-module-pms/yudao-module-pms-biz/src/test/java/cn/iocoder/yudao/module/pms/service/project/ProjectServiceImplTest.java index b62c3f3f8..2cfdea89f 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/test/java/cn/iocoder/yudao/module/pms/service/project/ProjectServiceImplTest.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/test/java/cn/iocoder/yudao/module/pms/service/project/ProjectServiceImplTest.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.pms.service.project; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; import jakarta.annotation.Resource; @@ -13,20 +12,14 @@ import cn.iocoder.yudao.module.pms.dal.dataobject.project.ProjectDO; import cn.iocoder.yudao.module.pms.dal.mysql.project.ProjectMapper; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import jakarta.annotation.Resource; import org.springframework.context.annotation.Import; -import java.util.*; -import java.time.LocalDateTime; -import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; /** * {@link ProjectServiceImpl} 的单元测试类 @@ -48,7 +41,7 @@ public class ProjectServiceImplTest extends BaseDbUnitTest { ProjectSaveReqVO createReqVO = randomPojo(ProjectSaveReqVO.class).setId(null); // 调用 - Long projectId = projectService.createProject(createReqVO); + Long projectId = projectService.createProject(1L, createReqVO); // 断言 assertNotNull(projectId); // 校验记录的属性是否正确