Merge branch 'master-jdk21' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
# Conflicts: # pom.xml # yudao-dependencies/pom.xml # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java # yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueSaveReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmBusinessFollowUpHandler.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmClueFollowUpHandler.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContactFollowUpHandler.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContractFollowUpHandler.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmCustomerFollowUpHandler.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmBacklogServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/bo/CrmPermissionUpdateReqBO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java # yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeSaveReqVO.java
This commit is contained in:
@@ -6,16 +6,15 @@ import cn.iocoder.yudao.framework.common.util.io.IoUtils;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
|
||||
import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
|
||||
import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyService;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -27,9 +26,6 @@ public class BpmProcessInstanceController {
|
||||
@Resource
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceCopyService processInstanceCopyService;
|
||||
|
||||
@GetMapping("/my-page")
|
||||
@Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中,进行调用")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
|
||||
@@ -61,21 +57,4 @@ public class BpmProcessInstanceController {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// TODO @kyle:抄送要不单独 controller?
|
||||
|
||||
@PostMapping("/cc/create")
|
||||
@Operation(summary = "抄送流程")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:create')")
|
||||
public CommonResult<Boolean> createProcessInstanceCC(@Valid @RequestBody BpmProcessInstanceCCReqVO createReqVO) {
|
||||
return success(processInstanceCopyService.ccProcessInstance(getLoginUserId(), createReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/cc/my-page")
|
||||
@Operation(summary = "获得抄送流程分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:query')")
|
||||
public CommonResult<PageResult<BpmProcessInstanceCCPageItemRespVO>> getProcessInstanceCCPage(
|
||||
@Valid BpmProcessInstanceCCMyPageReqVO pageReqVO) {
|
||||
return success(processInstanceCopyService.getMyProcessInstanceCCPage(getLoginUserId(), pageReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,77 @@
|
||||
package cn.iocoder.yudao.module.bpm.controller.admin.task;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyCreateReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyMyPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.convert.cc.BpmProcessInstanceCopyConvert;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.cc.BpmProcessInstanceCopyService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - 流程实例抄送")
|
||||
@RestController
|
||||
@RequestMapping("/bpm/process-instance/cc")
|
||||
@Validated
|
||||
public class BpmProcessInstanceCopyController {
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceCopyService processInstanceCopyService;
|
||||
@Resource
|
||||
private BpmProcessInstanceService bpmProcessInstanceService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Resource
|
||||
private BpmTaskService bpmTaskService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "抄送流程")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:create')")
|
||||
public CommonResult<Boolean> createProcessInstanceCopy(@Valid @RequestBody BpmProcessInstanceCopyCreateReqVO createReqVO) {
|
||||
processInstanceCopyService.createProcessInstanceCopy(getLoginUserId(), createReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/my-page")
|
||||
@Operation(summary = "获得抄送流程分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:query')")
|
||||
public CommonResult<PageResult<BpmProcessInstanceCopyPageItemRespVO>> getProcessInstanceCopyPage(
|
||||
@Valid BpmProcessInstanceCopyMyPageReqVO pageReqVO) {
|
||||
PageResult<BpmProcessInstanceCopyDO> pageResult = processInstanceCopyService.getMyProcessInstanceCopyPage(getLoginUserId(), pageReqVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(new PageResult<>(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 拼接返回
|
||||
Map<String, String> taskNameMap = bpmTaskService.getTaskNameByTaskIds(
|
||||
convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getTaskId));
|
||||
Map<String, String> processNameMap = bpmProcessInstanceService.getProcessInstanceNameMap(
|
||||
convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessInstanceId));
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(),
|
||||
copy -> Stream.of(copy.getStartUserId(), Long.parseLong(copy.getCreator()))));
|
||||
return success(BpmProcessInstanceCopyConvert.INSTANCE.convertPage(pageResult, taskNameMap, processNameMap, userMap));
|
||||
}
|
||||
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
// TODO @kyle:这个 VO 可以改成 BpmProcessInstanceCopyCreateReqVO
|
||||
@Schema(description = "管理后台 - 流程实例的抄送 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmProcessInstanceCCReqVO extends BpmTaskCandidateRuleVO {
|
||||
|
||||
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotEmpty(message = "任务编号不能为空")
|
||||
private String taskKey;
|
||||
|
||||
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotEmpty(message = "任务名称不能为空")
|
||||
private String taskName;
|
||||
|
||||
@Schema(description = "流程实例的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotEmpty(message = "流程实例的编号不能为空")
|
||||
private String processInstanceKey;
|
||||
|
||||
@Schema(description = "发起流程的用户的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "发起流程的用户的编号不能为空")
|
||||
private Long startUserId;
|
||||
|
||||
@Schema(description = "任务实例名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotEmpty(message = "任务实例名称不能为空")
|
||||
private String processInstanceName;
|
||||
|
||||
@Schema(description = "抄送原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "请帮忙审查下!")
|
||||
@NotBlank(message = "抄送原因不能为空")
|
||||
private String reason;
|
||||
|
||||
// TODO @kyle:看了下字段有点多,尽量不传递可推导的字段;
|
||||
// 需要传递:taskId(任务编号)、reason、userIds(被抄送的人)
|
||||
// 不需要传递:taskKey、taskName、processInstanceKey、startUserId、processInstanceName 因为这些可以后端查询到
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 流程实例抄送的创建 Request VO")
|
||||
@Data
|
||||
public class BpmProcessInstanceCopyCreateReqVO {
|
||||
|
||||
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotEmpty(message = "任务编号不能为空")
|
||||
private String taskId;
|
||||
|
||||
@Schema(description = "抄送原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "请帮忙审查下!")
|
||||
@NotBlank(message = "抄送原因不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
@@ -11,12 +11,11 @@ import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
// TODO @kyle:建议改成 BpmProcessInstanceCopyMyPageReqVO;cc 缩写不容易理解,所以改成 copy,虽然会长一点,但是可读性更重要;
|
||||
@Schema(description = "管理后台 - 流程实例抄送的分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmProcessInstanceCCMyPageReqVO extends PageParam {
|
||||
public class BpmProcessInstanceCopyMyPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "流程名称", example = "芋道")
|
||||
private String processInstanceName;
|
@@ -7,35 +7,23 @@ import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 流程实例抄送的分页 Item Response VO")
|
||||
@Data
|
||||
public class BpmProcessInstanceCCPageItemRespVO {
|
||||
public class BpmProcessInstanceCopyPageItemRespVO {
|
||||
|
||||
// TODO @kyle:如果已经写了 swagger 注解,可以不用写 java 注释哈;
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@Schema(description = "抄送主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 发起人Id
|
||||
*/
|
||||
@Schema(description = "发起人Id")
|
||||
@Schema(description = "发起人 ID")
|
||||
private Long startUserId;
|
||||
|
||||
@Schema(description = "发起人别名")
|
||||
private String startUserNickname;
|
||||
|
||||
/**
|
||||
* 流程主键
|
||||
*/
|
||||
@Schema(description = "流程实例的主键")
|
||||
private String processInstanceId;
|
||||
|
||||
@Schema(description = "流程实例的名称")
|
||||
private String processInstanceName;
|
||||
/**
|
||||
* 任务主键
|
||||
*/
|
||||
|
||||
@Schema(description = "发起抄送的任务编号")
|
||||
private String taskId;
|
||||
|
@@ -2,18 +2,18 @@ package cn.iocoder.yudao.module.bpm.convert.cc;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCPageItemRespVO;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
|
||||
import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyVO;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
// TODO kyle:类注释不太对
|
||||
/**
|
||||
* 动态表单 Convert
|
||||
* 流程抄送 Convert
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@@ -22,39 +22,18 @@ public interface BpmProcessInstanceCopyConvert {
|
||||
|
||||
BpmProcessInstanceCopyConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceCopyConvert.class);
|
||||
|
||||
// TODO @kyle:可以使用 BeanUtils copy 替代这些简单的哈;
|
||||
BpmProcessInstanceCopyDO copy(BpmProcessInstanceCopyDO bean);
|
||||
|
||||
BpmProcessInstanceCopyVO convert(BpmProcessInstanceCopyDO bean);
|
||||
|
||||
List<BpmProcessInstanceCCPageItemRespVO> convertList(List<BpmProcessInstanceCopyDO> list);
|
||||
|
||||
// TODO @kyle:/* taskId */ 这种注释一般不用写,可以一眼看明白的;避免变量看着略微不清晰哈
|
||||
default PageResult<BpmProcessInstanceCCPageItemRespVO> convertPage(PageResult<BpmProcessInstanceCopyDO> page
|
||||
, Map<String/* taskId */, String/* taskName */> taskMap
|
||||
, Map<String/* processInstaneId */, String/* processInstaneName */> processInstaneMap
|
||||
, Map<Long/* userId */, String/* userName */> userMap
|
||||
) {
|
||||
List<BpmProcessInstanceCCPageItemRespVO> list = convertList(page.getList());
|
||||
for (BpmProcessInstanceCCPageItemRespVO vo : list) {
|
||||
MapUtils.findAndThen(userMap, Long.valueOf(vo.getCreator()),
|
||||
vo::setCreatorNickname);
|
||||
MapUtils.findAndThen(userMap, vo.getStartUserId(),
|
||||
vo::setStartUserNickname);
|
||||
MapUtils.findAndThen(taskMap, vo.getTaskId(),
|
||||
vo::setTaskName);
|
||||
MapUtils.findAndThen(processInstaneMap, vo.getProcessInstanceId(),
|
||||
vo::setProcessInstanceName);
|
||||
}
|
||||
// TODO @kyle:可以精简成下面的哈;
|
||||
// List<BpmProcessInstanceCCPageItemRespVO> list2 = BeanUtils.toBean(page.getList(),
|
||||
// BpmProcessInstanceCCPageItemRespVO.class,
|
||||
// copy -> {
|
||||
// MapUtils.findAndThen(userMap, Long.valueOf(copy.getCreator()), copy::setCreatorNickname);
|
||||
// MapUtils.findAndThen(userMap, copy.getStartUserId(), copy::setStartUserNickname);
|
||||
// MapUtils.findAndThen(taskMap, copy.getTaskId(), copy::setTaskName);
|
||||
// MapUtils.findAndThen(processInstaneMap, copy.getProcessInstanceId(), copy::setProcessInstanceName);
|
||||
// });
|
||||
default PageResult<BpmProcessInstanceCopyPageItemRespVO> convertPage(PageResult<BpmProcessInstanceCopyDO> page,
|
||||
Map<String, String> taskNameMap,
|
||||
Map<String, String> processInstaneNameMap,
|
||||
Map<Long, AdminUserRespDTO> userMap) {
|
||||
List<BpmProcessInstanceCopyPageItemRespVO> list = BeanUtils.toBean(page.getList(),
|
||||
BpmProcessInstanceCopyPageItemRespVO.class,
|
||||
copy -> {
|
||||
MapUtils.findAndThen(userMap, Long.valueOf(copy.getCreator()), user -> user.setNickname(user.getNickname()));
|
||||
MapUtils.findAndThen(userMap, copy.getStartUserId(), user -> copy.setStartUserNickname(user.getNickname()));
|
||||
MapUtils.findAndThen(taskNameMap, copy.getTaskId(), copy::setTaskName);
|
||||
MapUtils.findAndThen(processInstaneNameMap, copy.getProcessInstanceId(), copy::setProcessInstanceName);
|
||||
});
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,7 @@ import lombok.*;
|
||||
* 流程抄送 DO
|
||||
*
|
||||
* @author kyle
|
||||
* @date 2022-05-19 TODO @kyle:@date 不是标准 java doc,可以使用 @since 替代,然后日期是不是不对
|
||||
* @since 2024-01-22
|
||||
*/
|
||||
@TableName(value = "bpm_process_instance_copy", autoResultMap = true)
|
||||
@Data
|
||||
@@ -26,13 +26,16 @@ public class BpmProcessInstanceCopyDO extends BaseDO {
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
// TODO @kyle:字段如果是关联或者冗余,要写下注释。以 processInstanceId 举例子。
|
||||
/**
|
||||
* 发起人 Id
|
||||
*
|
||||
* 关联 system_users 的 id 属性
|
||||
*/
|
||||
private Long startUserId;
|
||||
/**
|
||||
* 流程名
|
||||
*
|
||||
* 冗余 ProcessInstance 的 name 字段
|
||||
*/
|
||||
private String processInstanceName;
|
||||
/**
|
||||
@@ -44,16 +47,22 @@ public class BpmProcessInstanceCopyDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 任务主键
|
||||
*
|
||||
* 关联 Task 的 id 属性
|
||||
*/
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*
|
||||
* 冗余 Task 的 name 属性
|
||||
*/
|
||||
private String taskName;
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*
|
||||
* 关联 system_users 的 id 属性
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
@@ -62,10 +71,11 @@ public class BpmProcessInstanceCopyDO extends BaseDO {
|
||||
*/
|
||||
private String reason;
|
||||
|
||||
// TODO @kyle:这个字段,可以用 category 简化点
|
||||
/**
|
||||
* 流程分类
|
||||
*
|
||||
* 冗余 ProcessInstance 的 category 字段
|
||||
*/
|
||||
private String processDefinitionCategory;
|
||||
private String category;
|
||||
|
||||
}
|
||||
|
@@ -3,13 +3,14 @@ package cn.iocoder.yudao.module.bpm.dal.mysql.cc;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCMyPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyMyPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface BpmProcessInstanceCopyMapper extends BaseMapperX<BpmProcessInstanceCopyDO> { // TODO @kyle:方法和类之间要空行下;
|
||||
default PageResult<BpmProcessInstanceCopyDO> selectPage(Long loginUserId, BpmProcessInstanceCCMyPageReqVO reqVO){
|
||||
public interface BpmProcessInstanceCopyMapper extends BaseMapperX<BpmProcessInstanceCopyDO> {
|
||||
|
||||
default PageResult<BpmProcessInstanceCopyDO> selectPage(Long loginUserId, BpmProcessInstanceCopyMyPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<BpmProcessInstanceCopyDO>()
|
||||
.eqIfPresent(BpmProcessInstanceCopyDO::getUserId, loginUserId)
|
||||
.eqIfPresent(BpmProcessInstanceCopyDO::getProcessInstanceId, reqVO.getProcessInstanceId())
|
||||
|
@@ -0,0 +1,36 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.bpm.listener;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.bpm.api.listener.BpmResultListenerApi;
|
||||
import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO;
|
||||
import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO @芋艿:后续改成支持 RPC
|
||||
/**
|
||||
* 业务流程结果监听器实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Component
|
||||
public class BpmServiceResultListener implements ApplicationListener<BpmProcessInstanceResultEvent> {
|
||||
|
||||
@Resource
|
||||
private List<BpmResultListenerApi> bpmResultListenerApis;
|
||||
|
||||
@Override
|
||||
public final void onApplicationEvent(BpmProcessInstanceResultEvent event) {
|
||||
bpmResultListenerApis.forEach(bpmResultListenerApi -> {
|
||||
if (!StrUtil.equals(event.getProcessDefinitionKey(), bpmResultListenerApi.getProcessDefinitionKey())) {
|
||||
return;
|
||||
}
|
||||
bpmResultListenerApi.onEvent(BeanUtils.toBean(event, BpmResultListenerRespDTO.class));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.handler;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
|
||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
// TODO @芋艿:bpmn 分配人融合时,需要搞下这块;
|
||||
/**
|
||||
* 多实例处理类
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Component("multiInstanceHandler")
|
||||
public class MultiInstanceHandler {
|
||||
|
||||
@Resource
|
||||
private AdminUserApi userApi;
|
||||
|
||||
@Resource
|
||||
private PermissionApi permissionApi;
|
||||
|
||||
/**
|
||||
* 流程发起人那种情况不需要处理,
|
||||
* 由 flowable 完成
|
||||
*
|
||||
* @param execution flowable的执行对象
|
||||
* @return 用户ID
|
||||
*/
|
||||
public Set<String> getUserIds(DelegateExecution execution) {
|
||||
Set<String> candidateUserIds = new LinkedHashSet<>();
|
||||
FlowElement flowElement = execution.getCurrentFlowElement();
|
||||
if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask userTask) {
|
||||
String dataType = userTask.getAttributeValue(BpmnModelConstants.NAMESPACE, BpmnModelConstants.PROCESS_CUSTOM_DATA_TYPE);
|
||||
if ("USERS".equals(dataType) && CollUtil.isNotEmpty(userTask.getCandidateUsers())) {
|
||||
// 添加候选用户id
|
||||
candidateUserIds.addAll(userTask.getCandidateUsers());
|
||||
} else if (CollUtil.isNotEmpty(userTask.getCandidateGroups())) {
|
||||
// 获取组的ID,角色ID集合或部门ID集合
|
||||
List<Long> groups = userTask.getCandidateGroups().stream()
|
||||
// 例如部门DEPT100,100才是部门id
|
||||
.map(item -> Long.parseLong(item.substring(4)))
|
||||
.collect(Collectors.toList());
|
||||
List<Long> userIds = new ArrayList<>();
|
||||
if ("ROLES".equals(dataType)) {
|
||||
// 通过角色id,获取所有用户id集合
|
||||
Set<Long> userRoleIdListByRoleIds = permissionApi.getUserRoleIdListByRoleIds(groups);
|
||||
userIds = new ArrayList<>(userRoleIdListByRoleIds);
|
||||
} else if ("DEPTS".equals(dataType)) {
|
||||
// 通过部门id,获取所有用户id集合
|
||||
List<AdminUserRespDTO> userListByDeptIds = userApi.getUserListByDeptIds(groups);
|
||||
userIds = convertList(userListByDeptIds, AdminUserRespDTO::getId);
|
||||
}
|
||||
// 添加候选用户id
|
||||
userIds.forEach(id -> candidateUserIds.add(String.valueOf(id)));
|
||||
}
|
||||
}
|
||||
return candidateUserIds;
|
||||
}
|
||||
|
||||
}
|
@@ -50,4 +50,5 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
|
||||
protected void processCompleted(FlowableEngineEntityEvent event) {
|
||||
processInstanceService.updateProcessInstanceExtComplete((ProcessInstance)event.getEntity());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,12 +2,12 @@ package cn.iocoder.yudao.module.bpm.service.candidate;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -18,11 +18,6 @@ import java.util.Set;
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class BpmCandidateSourceInfo {
|
||||
|
||||
@Schema(description = "流程id")
|
||||
@NotNull
|
||||
private String processInstanceId;
|
||||
|
||||
@Schema(description = "当前任务ID")
|
||||
@NotNull
|
||||
private String taskId;
|
||||
|
@@ -1,53 +0,0 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.cc;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCMyPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo;
|
||||
|
||||
// TODO @kyle:这个 Service 要不挪到 task 包下;保持统一,task 下有流程、任务、抄送等;
|
||||
// TODO @kyle:中文和英文之间,有个空格,会更清晰点;例如说;流程抄送 Service 接口;中文写作习惯~
|
||||
/**
|
||||
* 流程抄送Service接口
|
||||
*
|
||||
* 现在是在审批的时候进行流程抄送
|
||||
*/
|
||||
public interface BpmProcessInstanceCopyService {
|
||||
|
||||
// TODO @kyle:无用的方法,可以去掉哈;另外,考虑到避免过多的 VO,这里就可以返回 BpmProcessInstanceCopyDO
|
||||
/**
|
||||
* 查询流程抄送
|
||||
*
|
||||
* @param copyId 流程抄送主键
|
||||
* @return 流程抄送
|
||||
*/
|
||||
BpmProcessInstanceCopyVO queryById(Long copyId);
|
||||
|
||||
// TODO 芋艿:这块要 review 下;思考下~~
|
||||
/**
|
||||
* 抄送
|
||||
* @param sourceInfo 抄送源信息,方便抄送处理
|
||||
* @return
|
||||
*/
|
||||
boolean makeCopy(BpmCandidateSourceInfo sourceInfo);
|
||||
|
||||
// TODO @kyle:可以方法名改成 createProcessInstanceCopy;现在项目一般新增都用 create 为主;
|
||||
/**
|
||||
* 流程实例的抄送
|
||||
*
|
||||
* @param userId 当前登录用户
|
||||
* @param createReqVO 创建的抄送请求
|
||||
* @return 是否抄送成功,抄送成功则返回true TODO @kyle:这里可以不用返回哈;目前一般是失败,就抛出业务异常;
|
||||
*/
|
||||
boolean ccProcessInstance(Long userId, BpmProcessInstanceCCReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 抄送的流程
|
||||
* @param loginUserId 登录用户id
|
||||
* @param pageReqVO 分页请求
|
||||
* @return 抄送的分页结果
|
||||
*/
|
||||
PageResult<BpmProcessInstanceCCPageItemRespVO> getMyProcessInstanceCCPage(Long loginUserId,
|
||||
BpmProcessInstanceCCMyPageReqVO pageReqVO);
|
||||
}
|
@@ -1,165 +0,0 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.cc;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCMyPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.convert.cc.BpmProcessInstanceCopyConvert;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.cc.BpmProcessInstanceCopyMapper;
|
||||
import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo;
|
||||
import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain;
|
||||
import cn.iocoder.yudao.module.bpm.service.cc.dto.BpmDelegateExecutionDTO;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
||||
import cn.iocoder.yudao.module.bpm.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.repository.ProcessDefinition;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// TODO @kyle:类注释要写下
|
||||
@Slf4j // TODO @kyle:按照 @Service、@Validated、@Slf4j,从重要到不重要的顺序;
|
||||
@Service
|
||||
@Validated
|
||||
public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopyService {
|
||||
@Resource // TODO @kyle:第一个变量,和类之间要有空行;
|
||||
private BpmProcessInstanceCopyMapper processInstanceCopyMapper;
|
||||
|
||||
/**
|
||||
* 和flowable有关的,查询流程名用的 TODO @kyle:可以不写哈注释;
|
||||
*/
|
||||
@Resource
|
||||
private RuntimeService runtimeService;
|
||||
|
||||
/**
|
||||
* 找抄送人用的 TODO @kyle:可以不写哈注释;
|
||||
*/
|
||||
@Resource
|
||||
private BpmCandidateSourceInfoProcessorChain processorChain;
|
||||
|
||||
// TODO @kyle:多余的变量,可以去掉哈
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmTaskService bpmTaskService;
|
||||
@Resource
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmProcessInstanceService bpmProcessInstanceService;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Override
|
||||
public BpmProcessInstanceCopyVO queryById(Long copyId) {
|
||||
BpmProcessInstanceCopyDO bpmProcessInstanceCopyDO = processInstanceCopyMapper.selectById(copyId);
|
||||
return BpmProcessInstanceCopyConvert.INSTANCE.convert(bpmProcessInstanceCopyDO);
|
||||
}
|
||||
|
||||
// TODO @kyle:makeCopy 和 ccProcessInstance 的调用关系,感受上反了;
|
||||
// makeCopy 有点像基于规则,查找抄送人,然后创建;
|
||||
// ccProcessInstance 是已经有了抄送人,然后创建;
|
||||
// 建议的改造:独立基于 processInstanceCopyMapper 做 insert
|
||||
@Override
|
||||
public boolean makeCopy(BpmCandidateSourceInfo sourceInfo) {
|
||||
if (null == sourceInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DelegateExecution executionEntity = new BpmDelegateExecutionDTO(sourceInfo.getProcessInstanceId());
|
||||
Set<Long> ccCandidates = processorChain.calculateTaskCandidateUsers(executionEntity, sourceInfo);
|
||||
if (CollUtil.isEmpty(ccCandidates)) {
|
||||
log.warn("相关抄送人不存在 {}", sourceInfo.getTaskId());
|
||||
return false;
|
||||
} else {
|
||||
BpmProcessInstanceCopyDO copyDO = new BpmProcessInstanceCopyDO();
|
||||
// 调用
|
||||
// 设置任务id
|
||||
copyDO.setTaskId(sourceInfo.getTaskId());
|
||||
copyDO.setTaskName(FlowableUtils.getTaskNameByTaskId(sourceInfo.getTaskId()));
|
||||
copyDO.setProcessInstanceId(sourceInfo.getProcessInstanceId());
|
||||
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
|
||||
.processInstanceId(sourceInfo.getProcessInstanceId())
|
||||
.singleResult();
|
||||
if (null == processInstance) {
|
||||
log.warn("相关流程实例不存在 {}", sourceInfo.getTaskId());
|
||||
return false;
|
||||
}
|
||||
copyDO.setStartUserId(FlowableUtils.getStartUserIdFromProcessInstance(processInstance));
|
||||
copyDO.setProcessInstanceName(processInstance.getName());
|
||||
ProcessDefinition processDefinition = FlowableUtils.getProcessDefinition(processInstance.getProcessDefinitionId());
|
||||
copyDO.setProcessDefinitionCategory(processDefinition.getCategory());
|
||||
copyDO.setReason(sourceInfo.getReason());
|
||||
copyDO.setCreator(sourceInfo.getCreator());
|
||||
copyDO.setCreateTime(LocalDateTime.now());
|
||||
List<BpmProcessInstanceCopyDO> copyList = new ArrayList<>(ccCandidates.size());
|
||||
for (Long userId : ccCandidates) {
|
||||
BpmProcessInstanceCopyDO copy = BpmProcessInstanceCopyConvert.INSTANCE.copy(copyDO);
|
||||
copy.setUserId(userId);
|
||||
copyList.add(copy);
|
||||
}
|
||||
return processInstanceCopyMapper.insertBatch(copyList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ccProcessInstance(Long userId, BpmProcessInstanceCCReqVO reqVO) {
|
||||
// 在能正常审批的情况下抄送流程
|
||||
BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo();
|
||||
sourceInfo.setTaskId(reqVO.getTaskKey());
|
||||
sourceInfo.setProcessInstanceId(reqVO.getProcessInstanceKey());
|
||||
sourceInfo.addRule(reqVO);
|
||||
sourceInfo.setCreator(String.valueOf(userId));
|
||||
sourceInfo.setReason(reqVO.getReason());
|
||||
if (!makeCopy(sourceInfo)) {
|
||||
throw new RuntimeException("抄送任务失败");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取流程抄送分页 TODO @kyle:接口已经注释,这里不用注释了哈;
|
||||
@Override
|
||||
public PageResult<BpmProcessInstanceCCPageItemRespVO> getMyProcessInstanceCCPage(Long loginUserId, BpmProcessInstanceCCMyPageReqVO pageReqVO) {
|
||||
// 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页
|
||||
// TODO @kyle:一般读逻辑,Service 返回 PageResult<BpmProcessInstanceCopyDO> 即可。关联数据的查询和拼接,交给 Controller;目的是:保证 Service 聚焦写逻辑,清晰简洁;
|
||||
PageResult<BpmProcessInstanceCopyDO> pageResult = processInstanceCopyMapper.selectPage(loginUserId, pageReqVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return new PageResult<>(pageResult.getTotal());
|
||||
}
|
||||
|
||||
// TODO @kyle:这种可以简洁点;参考如下
|
||||
// Map<String, ProcessInstance> processInstanceMap = bpmProcessInstanceService.getProcessInstanceMap(
|
||||
// convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessInstanceId));
|
||||
|
||||
Set<String/* taskId */> taskIds = new HashSet<>();
|
||||
Set<String/* processInstaneId */> processInstaneIds = new HashSet<>();
|
||||
Set<Long/* userId */> userIds = new HashSet<>();
|
||||
for (BpmProcessInstanceCopyDO doItem : pageResult.getList()) {
|
||||
taskIds.add(doItem.getTaskId());
|
||||
processInstaneIds.add(doItem.getProcessInstanceId());
|
||||
userIds.add(doItem.getStartUserId());
|
||||
Long userId = Long.valueOf(doItem.getCreator());
|
||||
userIds.add(userId);
|
||||
}
|
||||
|
||||
Map<String, String> taskNameByTaskIds = FlowableUtils.getTaskNameByTaskIds(taskIds);
|
||||
Map<String, String> processInstanceNameByTaskIds = FlowableUtils.getProcessInstanceNameByTaskIds(processInstaneIds);
|
||||
|
||||
Map<Long, String> userMap = adminUserApi.getUserList(userIds).stream().collect(Collectors.toMap(
|
||||
AdminUserRespDTO::getId, AdminUserRespDTO::getNickname));
|
||||
|
||||
// 转换返回
|
||||
return BpmProcessInstanceCopyConvert.INSTANCE.convertPage(pageResult, taskNameByTaskIds, processInstanceNameByTaskIds, userMap);
|
||||
}
|
||||
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.cc;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
// TODO @kyle:看看是不是要删除
|
||||
/**
|
||||
* 流程抄送视图对象 wf_copy
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2022-05-19
|
||||
*/
|
||||
@Data
|
||||
public class BpmProcessInstanceCopyVO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@Schema(description = "抄送主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 发起人Id
|
||||
*/
|
||||
@Schema(description = "发起人Id")
|
||||
private Long startUserId;
|
||||
|
||||
@Schema(description = "发起人别名")
|
||||
private String startUserNickname;
|
||||
|
||||
/**
|
||||
* 流程主键
|
||||
*/
|
||||
@Schema(description = "流程实例的主键")
|
||||
private String processInstanceId;
|
||||
|
||||
@Schema(description = "流程实例的名字")
|
||||
private String processInstanceName;
|
||||
|
||||
/**
|
||||
* 任务主键
|
||||
*/
|
||||
@Schema(description = "发起抄送的任务编号")
|
||||
private String taskId;
|
||||
|
||||
@Schema(description = "发起抄送的任务名称")
|
||||
private String taskName;
|
||||
/**
|
||||
* 用户主键
|
||||
*/
|
||||
@Schema(description = "用户编号")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "用户别名")
|
||||
private Long userNickname;
|
||||
|
||||
@Schema(description = "抄送原因")
|
||||
private String reason;
|
||||
|
||||
@Schema(description = "抄送人")
|
||||
private String creator;
|
||||
|
||||
@Schema(description = "抄送时间")
|
||||
private LocalDateTime createTime;
|
||||
}
|
@@ -2,10 +2,9 @@ package cn.iocoder.yudao.module.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
|
||||
import jakarta.validation.Valid;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* Flowable流程模型接口
|
||||
*
|
||||
@@ -62,7 +61,7 @@ public interface BpmModelService {
|
||||
/**
|
||||
* 修改模型的状态,实际更新的部署的流程定义的状态
|
||||
*
|
||||
* @param id 编号
|
||||
* @param id 编号
|
||||
* @param state 状态
|
||||
*/
|
||||
void updateModelState(String id, Integer state);
|
||||
|
@@ -14,6 +14,8 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.converter.BpmnXMLConverter;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
@@ -29,8 +31,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
@@ -5,8 +5,8 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
||||
import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
|
||||
import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
|
||||
import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
|
||||
@@ -17,6 +17,8 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.converter.BpmnXMLConverter;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
@@ -29,13 +31,10 @@ import org.flowable.engine.repository.ProcessDefinitionQuery;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;
|
||||
import static java.util.Collections.emptyList;
|
||||
@@ -53,8 +52,6 @@ import static java.util.Collections.emptyList;
|
||||
@Slf4j
|
||||
public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {
|
||||
|
||||
private static final String BPMN_FILE_SUFFIX = ".bpmn";
|
||||
|
||||
@Resource
|
||||
private RepositoryService repositoryService;
|
||||
|
||||
@@ -125,7 +122,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
|
||||
// 创建 Deployment 部署
|
||||
Deployment deploy = repositoryService.createDeployment()
|
||||
.key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
|
||||
.addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes())
|
||||
.addBytes(createReqDTO.getKey() + BpmnModelConstants.BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes())
|
||||
.tenantId(TenantContextHolder.getTenantIdStr())
|
||||
.deploy();
|
||||
|
||||
|
@@ -46,6 +46,17 @@ public interface BpmProcessInstanceService {
|
||||
return CollectionUtils.convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得流程实例名字 Map
|
||||
*
|
||||
* @param ids 流程实例的编号集合
|
||||
* @return 对应的映射关系
|
||||
*/
|
||||
default Map<String, String> getProcessInstanceNameMap(Set<String> ids) {
|
||||
return CollectionUtils.convertMap(getProcessInstances(ids),
|
||||
ProcessInstance::getProcessInstanceId, ProcessInstance::getName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得流程实例的分页
|
||||
*
|
||||
|
@@ -4,9 +4,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||
import jakarta.validation.Valid;
|
||||
import org.flowable.task.api.Task;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -132,6 +133,8 @@ public interface BpmTaskService {
|
||||
*/
|
||||
void updateTaskExtAssign(Task task);
|
||||
|
||||
Task getTask(String id);
|
||||
|
||||
/**
|
||||
* 获取当前任务的可回退的流程集合
|
||||
*
|
||||
@@ -181,4 +184,12 @@ public interface BpmTaskService {
|
||||
*/
|
||||
List<BpmTaskSubSignRespVO> getChildrenTaskList(String parentId);
|
||||
|
||||
/**
|
||||
* 通过任务 ID,查询任务名 Map
|
||||
*
|
||||
* @param taskIds 任务 ID
|
||||
* @return 任务 ID 与名字的 Map
|
||||
*/
|
||||
Map<String, String> getTaskNameByTaskIds(Collection<String> taskIds);
|
||||
|
||||
}
|
||||
|
@@ -19,14 +19,14 @@ import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
|
||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
|
||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskAddSignTypeEnum;
|
||||
import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo;
|
||||
import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyService;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
|
||||
import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
@@ -51,8 +51,6 @@ import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
@@ -96,9 +94,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
@Resource
|
||||
private ManagementService managementService;
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceCopyService processInstanceCopyService;
|
||||
|
||||
@Override
|
||||
public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {
|
||||
// 查询待办任务
|
||||
@@ -558,7 +553,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
return task;
|
||||
}
|
||||
|
||||
private Task getTask(String id) {
|
||||
@Override
|
||||
public Task getTask(String id) {
|
||||
return taskService.createTaskQuery().taskId(id).singleResult();
|
||||
}
|
||||
|
||||
@@ -971,4 +967,13 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
return BpmTaskConvert.INSTANCE.convertList(taskExtList, userMap, idTaskMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getTaskNameByTaskIds(Collection<String> taskIds) {
|
||||
if (CollUtil.isEmpty(taskIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<Task> tasks = taskService.createTaskQuery().taskIds(taskIds).list();
|
||||
return convertMap(tasks, Task::getId, Task::getName);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,40 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.task.cc;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyCreateReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyMyPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
|
||||
import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo;
|
||||
|
||||
/**
|
||||
* 流程抄送 Service 接口
|
||||
*
|
||||
* 现在是在审批的时候进行流程抄送
|
||||
*/
|
||||
public interface BpmProcessInstanceCopyService {
|
||||
|
||||
// TODO 芋艿:这块要 review 下;思考下~~
|
||||
/**
|
||||
* 抄送
|
||||
* @param sourceInfo 抄送源信息,方便抄送处理
|
||||
* @return
|
||||
*/
|
||||
boolean makeCopy(BpmCandidateSourceInfo sourceInfo);
|
||||
|
||||
/**
|
||||
* 流程实例的抄送
|
||||
*
|
||||
* @param userId 当前登录用户
|
||||
* @param createReqVO 创建的抄送请求
|
||||
*/
|
||||
void createProcessInstanceCopy(Long userId, BpmProcessInstanceCopyCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 抄送的流程的分页
|
||||
* @param userId 当前登录用户
|
||||
* @param pageReqVO 分页请求
|
||||
* @return 抄送的分页结果
|
||||
*/
|
||||
PageResult<BpmProcessInstanceCopyDO> getMyProcessInstanceCopyPage(Long userId,
|
||||
BpmProcessInstanceCopyMyPageReqVO pageReqVO);
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.task.cc;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyCreateReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyMyPageReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.cc.BpmProcessInstanceCopyMapper;
|
||||
import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
|
||||
import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo;
|
||||
import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.cc.dto.BpmDelegateExecutionDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
/**
|
||||
* 流程抄送 Service 实现类
|
||||
*
|
||||
* @author kyle
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopyService {
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceCopyMapper processInstanceCopyMapper;
|
||||
|
||||
@Resource
|
||||
private RuntimeService runtimeService;
|
||||
|
||||
@Resource
|
||||
private BpmCandidateSourceInfoProcessorChain processorChain;
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
private BpmTaskService bpmTaskService;
|
||||
@Resource
|
||||
@Lazy
|
||||
private BpmProcessInstanceService bpmProcessInstanceService;
|
||||
|
||||
@Override
|
||||
public boolean makeCopy(BpmCandidateSourceInfo sourceInfo) {
|
||||
if (null == sourceInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Task task = bpmTaskService.getTask(sourceInfo.getTaskId());
|
||||
if (ObjectUtil.isNull(task)) {
|
||||
return false;
|
||||
}
|
||||
String processInstanceId = task.getProcessInstanceId();
|
||||
if (StrUtil.isBlank(processInstanceId)) {
|
||||
return false;
|
||||
}
|
||||
DelegateExecution executionEntity = new BpmDelegateExecutionDTO(processInstanceId);
|
||||
Set<Long> ccCandidates = processorChain.calculateTaskCandidateUsers(executionEntity, sourceInfo);
|
||||
if (CollUtil.isEmpty(ccCandidates)) {
|
||||
log.warn("相关抄送人不存在 {}", sourceInfo.getTaskId());
|
||||
return false;
|
||||
} else {
|
||||
BpmProcessInstanceCopyDO copyDO = new BpmProcessInstanceCopyDO();
|
||||
// 调用
|
||||
// 设置任务id
|
||||
copyDO.setTaskId(sourceInfo.getTaskId());
|
||||
copyDO.setTaskName(task.getName());
|
||||
copyDO.setProcessInstanceId(processInstanceId);
|
||||
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.singleResult();
|
||||
if (null == processInstance) {
|
||||
log.warn("相关流程实例不存在 {}", sourceInfo.getTaskId());
|
||||
return false;
|
||||
}
|
||||
copyDO.setStartUserId(Long.parseLong(processInstance.getStartUserId()));
|
||||
copyDO.setProcessInstanceName(processInstance.getName());
|
||||
copyDO.setCategory(processInstance.getProcessDefinitionCategory());
|
||||
copyDO.setReason(sourceInfo.getReason());
|
||||
copyDO.setCreator(sourceInfo.getCreator());
|
||||
copyDO.setCreateTime(LocalDateTime.now());
|
||||
List<BpmProcessInstanceCopyDO> copyList = new ArrayList<>(ccCandidates.size());
|
||||
for (Long userId : ccCandidates) {
|
||||
BpmProcessInstanceCopyDO copy = BeanUtil.copyProperties(copyDO, BpmProcessInstanceCopyDO.class);
|
||||
copy.setUserId(userId);
|
||||
copyList.add(copy);
|
||||
}
|
||||
return processInstanceCopyMapper.insertBatch(copyList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createProcessInstanceCopy(Long userId, BpmProcessInstanceCopyCreateReqVO reqVO) {
|
||||
// 1.1 校验任务存在
|
||||
Task task = bpmTaskService.getTask(reqVO.getTaskId());
|
||||
if (ObjectUtil.isNull(task)) {
|
||||
throw exception(ErrorCodeConstants.TASK_NOT_EXISTS);
|
||||
}
|
||||
// 1.2 校验流程存在
|
||||
String processInstanceId = task.getProcessInstanceId();
|
||||
ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(processInstanceId);
|
||||
if (processInstance == null) {
|
||||
log.warn("[createProcessInstanceCopy][任务({}) 对应的流程不存在]", reqVO.getTaskId());
|
||||
throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 2. 创建抄送流程
|
||||
BpmProcessInstanceCopyDO copy = new BpmProcessInstanceCopyDO()
|
||||
.setTaskId(reqVO.getTaskId()).setTaskName(task.getName())
|
||||
.setProcessInstanceId(processInstanceId).setStartUserId(Long.valueOf(processInstance.getStartUserId()))
|
||||
.setProcessInstanceName(processInstance.getName()).setCategory(processInstance.getProcessDefinitionCategory())
|
||||
.setReason(reqVO.getReason());
|
||||
processInstanceCopyMapper.insert(copy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BpmProcessInstanceCopyDO> getMyProcessInstanceCopyPage(Long userId, BpmProcessInstanceCopyMyPageReqVO pageReqVO) {
|
||||
return processInstanceCopyMapper.selectPage(userId, pageReqVO);
|
||||
}
|
||||
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.cc.dto;
|
||||
package cn.iocoder.yudao.module.bpm.service.task.cc.dto;
|
||||
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.bpmn.model.FlowableListener;
|
@@ -1,127 +0,0 @@
|
||||
package cn.iocoder.yudao.module.bpm.util;
|
||||
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.ExtensionElement;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.bpmn.model.FlowNode;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.engine.repository.ProcessDefinition;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.task.api.Task;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 流程引擎工具类封装
|
||||
*
|
||||
* @author: linjinp
|
||||
* @create: 2019-12-24 13:51
|
||||
**/
|
||||
public class FlowableUtils {
|
||||
|
||||
/**
|
||||
* 获取流程名称
|
||||
*
|
||||
* @param processDefinitionId
|
||||
* @return
|
||||
*/
|
||||
public static String getProcessDefinitionName(String processDefinitionId) {
|
||||
RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class);
|
||||
ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
|
||||
return processDefinition.getName();
|
||||
}
|
||||
|
||||
public static ProcessDefinition getProcessDefinition(String processDefinitionId) {
|
||||
RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class);
|
||||
return repositoryService.getProcessDefinition(processDefinitionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点数据
|
||||
*
|
||||
* @param processInstanceId
|
||||
* @param nodeId
|
||||
* @return
|
||||
*/
|
||||
public static FlowNode getFlowNode(String processInstanceId, String nodeId) {
|
||||
|
||||
RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class);
|
||||
RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class);
|
||||
|
||||
String definitionld = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId(); // 获取bpm(模型)对象
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionld);
|
||||
// 传节点定义key获取当前节点
|
||||
FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(nodeId);
|
||||
return flowNode;
|
||||
}
|
||||
|
||||
public static ExtensionElement generateFlowNodeIdExtension(String nodeId) {
|
||||
ExtensionElement extensionElement = new ExtensionElement();
|
||||
extensionElement.setElementText(nodeId);
|
||||
extensionElement.setName("nodeId");
|
||||
extensionElement.setNamespacePrefix("flowable");
|
||||
extensionElement.setNamespace("nodeId");
|
||||
return extensionElement;
|
||||
}
|
||||
|
||||
public static String getNodeIdFromExtension(FlowElement flowElement) {
|
||||
Map<String, List<ExtensionElement>> extensionElements = flowElement.getExtensionElements();
|
||||
return extensionElements.get("nodeId").get(0).getElementText();
|
||||
}
|
||||
|
||||
public static Long getStartUserIdFromProcessInstance(ProcessInstance instance) {
|
||||
if (null == instance) {
|
||||
return null;
|
||||
}
|
||||
return NumberUtils.parseLong(instance.getStartUserId());
|
||||
}
|
||||
|
||||
public static String getTaskNameByTaskId(String taskId) {
|
||||
TaskService taskService = SpringUtil.getBean(TaskService.class);
|
||||
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
|
||||
return task.getName();
|
||||
}
|
||||
|
||||
// TODO @kyle:Utils 里不做查询;可以封装到 bpmTaskService 里
|
||||
public static Map<String/* taskId */, String/* taskName */> getTaskNameByTaskIds(Collection<String> taskIds) {
|
||||
TaskService taskService = SpringUtil.getBean(TaskService.class);
|
||||
List<Task> tasks = taskService.createTaskQuery().taskIds(taskIds).list();
|
||||
if (CollUtil.isNotEmpty(tasks)) {
|
||||
Map<String/* taskId */, String/* taskName */> taskMap = new HashMap<>(tasks.size());
|
||||
for (Task task : tasks) {
|
||||
taskMap.putIfAbsent(task.getId(), task.getName());
|
||||
}
|
||||
return taskMap;
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public static String getProcessInstanceNameByTaskId(String processInstanceId) {
|
||||
RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class);
|
||||
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.singleResult();
|
||||
return processInstance.getName();
|
||||
}
|
||||
|
||||
// TODO @kyle:Utils 里不做查询;可以封装到 bpmTaskService 里
|
||||
public static Map<String/* processInstaneId */, String/* processInstaneName */> getProcessInstanceNameByTaskIds(Set<String> taskIds) {
|
||||
RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class);
|
||||
List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery().processInstanceIds(taskIds).list();
|
||||
if (CollUtil.isNotEmpty(processInstances)) {
|
||||
Map<String/* processInstaneId */, String/* processInstaneName */> processInstaneMap = new HashMap<>(processInstances.size());
|
||||
for (ProcessInstance processInstance : processInstances) {
|
||||
processInstaneMap.putIfAbsent(processInstance.getId(), processInstance.getName());
|
||||
}
|
||||
return processInstaneMap;
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.cc;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Import({BpmProcessInstanceCopyServiceImpl.class})
|
||||
class BpmProcessInstanceCopyServiceTest extends BaseDbUnitTest {
|
||||
@Resource
|
||||
private BpmProcessInstanceCopyServiceImpl service;
|
||||
|
||||
@Test
|
||||
void queryById() {
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user