Commit 3a4b0f4f75eb4c760df56f56414a9eed8bd20848
1 parent
40157244
合并bpm-base和bpm-flowable 为bpm-biz
Showing
153 changed files
with
7922 additions
and
4 deletions
yudao-module-bpm/pom.xml
| ... | ... | @@ -10,9 +10,10 @@ |
| 10 | 10 | <modelVersion>4.0.0</modelVersion> |
| 11 | 11 | <modules> |
| 12 | 12 | <module>yudao-module-bpm-api</module> |
| 13 | - <module>yudao-module-bpm-base</module> | |
| 14 | - <module>yudao-module-bpm-biz-flowable</module> | |
| 15 | - <module>yudao-module-bpm-biz-activiti</module> | |
| 13 | + <module>yudao-module-bpm-biz</module> | |
| 14 | +<!-- <module>yudao-module-bpm-base</module>--> | |
| 15 | +<!-- <module>yudao-module-bpm-biz-flowable</module>--> | |
| 16 | +<!-- <module>yudao-module-bpm-biz-activiti</module>--> | |
| 16 | 17 | </modules> |
| 17 | 18 | <artifactId>yudao-module-bpm</artifactId> |
| 18 | 19 | <packaging>pom</packaging> | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | |
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
| 5 | + <parent> | |
| 6 | + <groupId>cn.iocoder.boot</groupId> | |
| 7 | + <artifactId>yudao-module-bpm</artifactId> | |
| 8 | + <version>${revision}</version> | |
| 9 | + </parent> | |
| 10 | + <modelVersion>4.0.0</modelVersion> | |
| 11 | + <artifactId>yudao-module-bpm-biz</artifactId> | |
| 12 | + | |
| 13 | + <name>${project.artifactId}</name> | |
| 14 | + <description> | |
| 15 | + bpm-base 模块,实现公用的工作流的逻辑,提供给 bpm-activiti 和 bpm-flowable 复用 | |
| 16 | + </description> | |
| 17 | + | |
| 18 | + <dependencies> | |
| 19 | + <dependency> | |
| 20 | + <groupId>cn.iocoder.boot</groupId> | |
| 21 | + <artifactId>yudao-module-bpm-api</artifactId> | |
| 22 | + <version>${revision}</version> | |
| 23 | + </dependency> | |
| 24 | + <dependency> | |
| 25 | + <groupId>cn.iocoder.boot</groupId> | |
| 26 | + <artifactId>yudao-module-system-api</artifactId> | |
| 27 | + <version>${revision}</version> | |
| 28 | + </dependency> | |
| 29 | + | |
| 30 | + <!-- 业务组件 --> | |
| 31 | + <dependency> | |
| 32 | + <groupId>cn.iocoder.boot</groupId> | |
| 33 | + <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId> | |
| 34 | + </dependency> | |
| 35 | + <dependency> | |
| 36 | + <groupId>cn.iocoder.boot</groupId> | |
| 37 | + <artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId> | |
| 38 | + </dependency> | |
| 39 | + | |
| 40 | + <!-- Web 相关 --> | |
| 41 | + <dependency> | |
| 42 | + <groupId>cn.iocoder.boot</groupId> | |
| 43 | + <artifactId>yudao-spring-boot-starter-web</artifactId> | |
| 44 | + </dependency> | |
| 45 | + | |
| 46 | + <dependency> | |
| 47 | + <groupId>cn.iocoder.boot</groupId> | |
| 48 | + <artifactId>yudao-spring-boot-starter-security</artifactId> | |
| 49 | + </dependency> | |
| 50 | + | |
| 51 | + <!-- DB 相关 --> | |
| 52 | + <dependency> | |
| 53 | + <groupId>cn.iocoder.boot</groupId> | |
| 54 | + <artifactId>yudao-spring-boot-starter-mybatis</artifactId> | |
| 55 | + </dependency> | |
| 56 | + | |
| 57 | + <!-- Test 测试相关 --> | |
| 58 | + <dependency> | |
| 59 | + <groupId>cn.iocoder.boot</groupId> | |
| 60 | + <artifactId>yudao-spring-boot-starter-test</artifactId> | |
| 61 | + </dependency> | |
| 62 | + <!-- 工作流相关 --> | |
| 63 | + <dependency> | |
| 64 | + <groupId>cn.iocoder.boot</groupId> | |
| 65 | + <artifactId>yudao-spring-boot-starter-flowable</artifactId> | |
| 66 | + </dependency> | |
| 67 | + </dependencies> | |
| 68 | +</project> | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.api.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; | |
| 5 | +import org.springframework.stereotype.Service; | |
| 6 | +import org.springframework.validation.annotation.Validated; | |
| 7 | + | |
| 8 | +import javax.annotation.Resource; | |
| 9 | +import javax.validation.Valid; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * Flowable 流程实例 Api 实现类 | |
| 13 | + * | |
| 14 | + * @author 芋道源码 | |
| 15 | + * @author jason | |
| 16 | + */ | |
| 17 | +@Service | |
| 18 | +@Validated | |
| 19 | +public class BpmProcessInstanceApiImpl implements BpmProcessInstanceApi { | |
| 20 | + | |
| 21 | + @Resource | |
| 22 | + private BpmProcessInstanceService processInstanceService; | |
| 23 | + | |
| 24 | + @Override | |
| 25 | + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO) { | |
| 26 | + return processInstanceService.createProcessInstance(userId, reqDTO); | |
| 27 | + } | |
| 28 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.*; | |
| 4 | +import cn.iocoder.yudao.module.bpm.convert.definition.BpmFormConvert; | |
| 5 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService; | |
| 7 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 8 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 9 | +import io.swagger.annotations.Api; | |
| 10 | +import io.swagger.annotations.ApiImplicitParam; | |
| 11 | +import io.swagger.annotations.ApiOperation; | |
| 12 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 13 | +import org.springframework.validation.annotation.Validated; | |
| 14 | +import org.springframework.web.bind.annotation.*; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | +import javax.validation.Valid; | |
| 18 | +import java.util.List; | |
| 19 | + | |
| 20 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 21 | + | |
| 22 | +@Api(tags = "管理后台 - 动态表单") | |
| 23 | +@RestController | |
| 24 | +@RequestMapping("/bpm/form") | |
| 25 | +@Validated | |
| 26 | +public class BpmFormController { | |
| 27 | + | |
| 28 | + @Resource | |
| 29 | + private BpmFormService formService; | |
| 30 | + | |
| 31 | + @PostMapping("/create") | |
| 32 | + @ApiOperation("创建动态表单") | |
| 33 | + @PreAuthorize("@ss.hasPermission('bpm:form:create')") | |
| 34 | + public CommonResult<Long> createForm(@Valid @RequestBody BpmFormCreateReqVO createReqVO) { | |
| 35 | + return success(formService.createForm(createReqVO)); | |
| 36 | + } | |
| 37 | + | |
| 38 | + @PutMapping("/update") | |
| 39 | + @ApiOperation("更新动态表单") | |
| 40 | + @PreAuthorize("@ss.hasPermission('bpm:form:update')") | |
| 41 | + public CommonResult<Boolean> updateForm(@Valid @RequestBody BpmFormUpdateReqVO updateReqVO) { | |
| 42 | + formService.updateForm(updateReqVO); | |
| 43 | + return success(true); | |
| 44 | + } | |
| 45 | + | |
| 46 | + @DeleteMapping("/delete") | |
| 47 | + @ApiOperation("删除动态表单") | |
| 48 | + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | |
| 49 | + @PreAuthorize("@ss.hasPermission('bpm:form:delete')") | |
| 50 | + public CommonResult<Boolean> deleteForm(@RequestParam("id") Long id) { | |
| 51 | + formService.deleteForm(id); | |
| 52 | + return success(true); | |
| 53 | + } | |
| 54 | + | |
| 55 | + @GetMapping("/get") | |
| 56 | + @ApiOperation("获得动态表单") | |
| 57 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | |
| 58 | + @PreAuthorize("@ss.hasPermission('bpm:form:query')") | |
| 59 | + public CommonResult<BpmFormRespVO> getForm(@RequestParam("id") Long id) { | |
| 60 | + BpmFormDO form = formService.getForm(id); | |
| 61 | + return success(BpmFormConvert.INSTANCE.convert(form)); | |
| 62 | + } | |
| 63 | + | |
| 64 | + @GetMapping("/list-all-simple") | |
| 65 | + @ApiOperation(value = "获得动态表单的精简列表", notes = "用于表单下拉框") | |
| 66 | + public CommonResult<List<BpmFormSimpleRespVO>> getSimpleForms() { | |
| 67 | + List<BpmFormDO> list = formService.getFormList(); | |
| 68 | + return success(BpmFormConvert.INSTANCE.convertList2(list)); | |
| 69 | + } | |
| 70 | + | |
| 71 | + @GetMapping("/page") | |
| 72 | + @ApiOperation("获得动态表单分页") | |
| 73 | + @PreAuthorize("@ss.hasPermission('bpm:form:query')") | |
| 74 | + public CommonResult<PageResult<BpmFormRespVO>> getFormPage(@Valid BpmFormPageReqVO pageVO) { | |
| 75 | + PageResult<BpmFormDO> pageResult = formService.getFormPage(pageVO); | |
| 76 | + return success(BpmFormConvert.INSTANCE.convertPage(pageResult)); | |
| 77 | + } | |
| 78 | + | |
| 79 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.io.IoUtils; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; | |
| 7 | +import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert; | |
| 8 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; | |
| 9 | +import io.swagger.annotations.Api; | |
| 10 | +import io.swagger.annotations.ApiImplicitParam; | |
| 11 | +import io.swagger.annotations.ApiOperation; | |
| 12 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 13 | +import org.springframework.validation.annotation.Validated; | |
| 14 | +import org.springframework.web.bind.annotation.*; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | +import javax.validation.Valid; | |
| 18 | + | |
| 19 | +import java.io.IOException; | |
| 20 | + | |
| 21 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 22 | + | |
| 23 | +@Api(tags = "管理后台 - 流程模型") | |
| 24 | +@RestController | |
| 25 | +@RequestMapping("/bpm/model") | |
| 26 | +@Validated | |
| 27 | +public class BpmModelController { | |
| 28 | + | |
| 29 | + @Resource | |
| 30 | + private BpmModelService modelService; | |
| 31 | + | |
| 32 | + @GetMapping("/page") | |
| 33 | + @ApiOperation(value = "获得模型分页") | |
| 34 | + public CommonResult<PageResult<BpmModelPageItemRespVO>> getModelPage(BpmModelPageReqVO pageVO) { | |
| 35 | + return success(modelService.getModelPage(pageVO)); | |
| 36 | + } | |
| 37 | + | |
| 38 | + @GetMapping("/get") | |
| 39 | + @ApiOperation("获得模型") | |
| 40 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) | |
| 41 | + @PreAuthorize("@ss.hasPermission('bpm:model:query')") | |
| 42 | + public CommonResult<BpmModelRespVO> getModel(@RequestParam("id") String id) { | |
| 43 | + BpmModelRespVO model = modelService.getModel(id); | |
| 44 | + return success(model); | |
| 45 | + } | |
| 46 | + | |
| 47 | + @PostMapping("/create") | |
| 48 | + @ApiOperation(value = "新建模型") | |
| 49 | + @PreAuthorize("@ss.hasPermission('bpm:model:create')") | |
| 50 | + public CommonResult<String> createModel(@Valid @RequestBody BpmModelCreateReqVO createRetVO) { | |
| 51 | + return success(modelService.createModel(createRetVO, null)); | |
| 52 | + } | |
| 53 | + | |
| 54 | + @PutMapping("/update") | |
| 55 | + @ApiOperation(value = "修改模型") | |
| 56 | + @PreAuthorize("@ss.hasPermission('bpm:model:update')") | |
| 57 | + public CommonResult<Boolean> updateModel(@Valid @RequestBody BpmModelUpdateReqVO modelVO) { | |
| 58 | + modelService.updateModel(modelVO); | |
| 59 | + return success(true); | |
| 60 | + } | |
| 61 | + | |
| 62 | + @PostMapping("/import") | |
| 63 | + @ApiOperation(value = "导入模型") | |
| 64 | + @PreAuthorize("@ss.hasPermission('bpm:model:import')") | |
| 65 | + public CommonResult<String> importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException { | |
| 66 | + BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO); | |
| 67 | + // 读取文件 | |
| 68 | + String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false); | |
| 69 | + return success(modelService.createModel(createReqVO, bpmnXml)); | |
| 70 | + } | |
| 71 | + | |
| 72 | + @PostMapping("/deploy") | |
| 73 | + @ApiOperation(value = "部署模型") | |
| 74 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) | |
| 75 | + @PreAuthorize("@ss.hasPermission('bpm:model:deploy')") | |
| 76 | + public CommonResult<Boolean> deployModel(@RequestParam("id") String id) { | |
| 77 | + modelService.deployModel(id); | |
| 78 | + return success(true); | |
| 79 | + } | |
| 80 | + | |
| 81 | + @PutMapping("/update-state") | |
| 82 | + @ApiOperation(value = "修改模型的状态", notes = "实际更新的部署的流程定义的状态") | |
| 83 | + @PreAuthorize("@ss.hasPermission('bpm:model:update')") | |
| 84 | + public CommonResult<Boolean> updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) { | |
| 85 | + modelService.updateModelState(reqVO.getId(), reqVO.getState()); | |
| 86 | + return success(true); | |
| 87 | + } | |
| 88 | + | |
| 89 | + @DeleteMapping("/delete") | |
| 90 | + @ApiOperation("删除模型") | |
| 91 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) | |
| 92 | + @PreAuthorize("@ss.hasPermission('bpm:model:delete')") | |
| 93 | + public CommonResult<Boolean> deleteModel(@RequestParam("id") String id) { | |
| 94 | + modelService.deleteModel(id); | |
| 95 | + return success(true); | |
| 96 | + } | |
| 97 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; | |
| 10 | +import io.swagger.annotations.Api; | |
| 11 | +import io.swagger.annotations.ApiImplicitParam; | |
| 12 | +import io.swagger.annotations.ApiOperation; | |
| 13 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 14 | +import org.springframework.validation.annotation.Validated; | |
| 15 | +import org.springframework.web.bind.annotation.GetMapping; | |
| 16 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 17 | +import org.springframework.web.bind.annotation.RequestParam; | |
| 18 | +import org.springframework.web.bind.annotation.RestController; | |
| 19 | + | |
| 20 | +import javax.annotation.Resource; | |
| 21 | + | |
| 22 | +import java.util.List; | |
| 23 | + | |
| 24 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 25 | + | |
| 26 | +@Api(tags = "管理后台 - 流程定义") | |
| 27 | +@RestController | |
| 28 | +@RequestMapping("/bpm/process-definition") | |
| 29 | +@Validated | |
| 30 | +public class BpmProcessDefinitionController { | |
| 31 | + | |
| 32 | + @Resource | |
| 33 | + private BpmProcessDefinitionService bpmDefinitionService; | |
| 34 | + | |
| 35 | + @GetMapping("/page") | |
| 36 | + @ApiOperation(value = "获得流程定义分页") | |
| 37 | + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')") | |
| 38 | + public CommonResult<PageResult<BpmProcessDefinitionPageItemRespVO>> getProcessDefinitionPage( | |
| 39 | + BpmProcessDefinitionPageReqVO pageReqVO) { | |
| 40 | + return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO)); | |
| 41 | + } | |
| 42 | + | |
| 43 | + @GetMapping ("/list") | |
| 44 | + @ApiOperation(value = "获得流程定义列表") | |
| 45 | + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')") | |
| 46 | + public CommonResult<List<BpmProcessDefinitionRespVO>> getProcessDefinitionList( | |
| 47 | + BpmProcessDefinitionListReqVO listReqVO) { | |
| 48 | + return success(bpmDefinitionService.getProcessDefinitionList(listReqVO)); | |
| 49 | + } | |
| 50 | + | |
| 51 | + @GetMapping ("/get-bpmn-xml") | |
| 52 | + @ApiOperation(value = "获得流程定义的 BPMN XML") | |
| 53 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) | |
| 54 | + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')") | |
| 55 | + public CommonResult<String> getProcessDefinitionBpmnXML(@RequestParam("id") String id) { | |
| 56 | + String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id); | |
| 57 | + return success(bpmnXML); | |
| 58 | + } | |
| 59 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; | |
| 8 | +import io.swagger.annotations.Api; | |
| 9 | +import io.swagger.annotations.ApiImplicitParam; | |
| 10 | +import io.swagger.annotations.ApiImplicitParams; | |
| 11 | +import io.swagger.annotations.ApiOperation; | |
| 12 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 13 | +import org.springframework.validation.annotation.Validated; | |
| 14 | +import org.springframework.web.bind.annotation.*; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | +import javax.validation.Valid; | |
| 18 | +import java.util.List; | |
| 19 | + | |
| 20 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 21 | + | |
| 22 | +@Api(tags = "管理后台 - 任务分配规则") | |
| 23 | +@RestController | |
| 24 | +@RequestMapping("/bpm/task-assign-rule") | |
| 25 | +@Validated | |
| 26 | +public class BpmTaskAssignRuleController { | |
| 27 | + | |
| 28 | + @Resource | |
| 29 | + private BpmTaskAssignRuleService taskAssignRuleService; | |
| 30 | + | |
| 31 | + @GetMapping("/list") | |
| 32 | + @ApiOperation(value = "获得任务分配规则列表") | |
| 33 | + @ApiImplicitParams({ | |
| 34 | + @ApiImplicitParam(name = "modelId", value = "模型编号", example = "1024", dataTypeClass = String.class), | |
| 35 | + @ApiImplicitParam(name = "processDefinitionId", value = "流程定义的编号", example = "2048", dataTypeClass = String.class) | |
| 36 | + }) | |
| 37 | + @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')") | |
| 38 | + public CommonResult<List<BpmTaskAssignRuleRespVO>> getTaskAssignRuleList( | |
| 39 | + @RequestParam(value = "modelId", required = false) String modelId, | |
| 40 | + @RequestParam(value = "processDefinitionId", required = false) String processDefinitionId) { | |
| 41 | + return success(taskAssignRuleService.getTaskAssignRuleList(modelId, processDefinitionId)); | |
| 42 | + } | |
| 43 | + | |
| 44 | + @PostMapping("/create") | |
| 45 | + @ApiOperation(value = "创建任务分配规则") | |
| 46 | + @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:create')") | |
| 47 | + public CommonResult<Long> createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) { | |
| 48 | + return success(taskAssignRuleService.createTaskAssignRule(reqVO)); | |
| 49 | + } | |
| 50 | + | |
| 51 | + @PutMapping("/update") | |
| 52 | + @ApiOperation(value = "更新任务分配规则") | |
| 53 | + @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:update')") | |
| 54 | + public CommonResult<Boolean> updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) { | |
| 55 | + taskAssignRuleService.updateTaskAssignRule(reqVO); | |
| 56 | + return success(true); | |
| 57 | + } | |
| 58 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupRespVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.convert.definition.BpmUserGroupConvert; | |
| 8 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; | |
| 10 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 11 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 12 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 13 | +import io.swagger.annotations.Api; | |
| 14 | +import io.swagger.annotations.ApiImplicitParam; | |
| 15 | +import io.swagger.annotations.ApiOperation; | |
| 16 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 17 | +import org.springframework.validation.annotation.Validated; | |
| 18 | +import org.springframework.web.bind.annotation.*; | |
| 19 | + | |
| 20 | +import javax.annotation.Resource; | |
| 21 | +import javax.validation.Valid; | |
| 22 | +import java.util.List; | |
| 23 | + | |
| 24 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 25 | + | |
| 26 | +@Api(tags = "管理后台 - 用户组") | |
| 27 | +@RestController | |
| 28 | +@RequestMapping("/bpm/user-group") | |
| 29 | +@Validated | |
| 30 | +public class BpmUserGroupController { | |
| 31 | + | |
| 32 | + @Resource | |
| 33 | + private BpmUserGroupService userGroupService; | |
| 34 | + | |
| 35 | + @PostMapping("/create") | |
| 36 | + @ApiOperation("创建用户组") | |
| 37 | + @PreAuthorize("@ss.hasPermission('bpm:user-group:create')") | |
| 38 | + public CommonResult<Long> createUserGroup(@Valid @RequestBody BpmUserGroupCreateReqVO createReqVO) { | |
| 39 | + return success(userGroupService.createUserGroup(createReqVO)); | |
| 40 | + } | |
| 41 | + | |
| 42 | + @PutMapping("/update") | |
| 43 | + @ApiOperation("更新用户组") | |
| 44 | + @PreAuthorize("@ss.hasPermission('bpm:user-group:update')") | |
| 45 | + public CommonResult<Boolean> updateUserGroup(@Valid @RequestBody BpmUserGroupUpdateReqVO updateReqVO) { | |
| 46 | + userGroupService.updateUserGroup(updateReqVO); | |
| 47 | + return success(true); | |
| 48 | + } | |
| 49 | + | |
| 50 | + @DeleteMapping("/delete") | |
| 51 | + @ApiOperation("删除用户组") | |
| 52 | + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | |
| 53 | + @PreAuthorize("@ss.hasPermission('bpm:user-group:delete')") | |
| 54 | + public CommonResult<Boolean> deleteUserGroup(@RequestParam("id") Long id) { | |
| 55 | + userGroupService.deleteUserGroup(id); | |
| 56 | + return success(true); | |
| 57 | + } | |
| 58 | + | |
| 59 | + @GetMapping("/get") | |
| 60 | + @ApiOperation("获得用户组") | |
| 61 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | |
| 62 | + @PreAuthorize("@ss.hasPermission('bpm:user-group:query')") | |
| 63 | + public CommonResult<BpmUserGroupRespVO> getUserGroup(@RequestParam("id") Long id) { | |
| 64 | + BpmUserGroupDO userGroup = userGroupService.getUserGroup(id); | |
| 65 | + return success(BpmUserGroupConvert.INSTANCE.convert(userGroup)); | |
| 66 | + } | |
| 67 | + | |
| 68 | + @GetMapping("/page") | |
| 69 | + @ApiOperation("获得用户组分页") | |
| 70 | + @PreAuthorize("@ss.hasPermission('bpm:user-group:query')") | |
| 71 | + public CommonResult<PageResult<BpmUserGroupRespVO>> getUserGroupPage(@Valid BpmUserGroupPageReqVO pageVO) { | |
| 72 | + PageResult<BpmUserGroupDO> pageResult = userGroupService.getUserGroupPage(pageVO); | |
| 73 | + return success(BpmUserGroupConvert.INSTANCE.convertPage(pageResult)); | |
| 74 | + } | |
| 75 | + | |
| 76 | + @GetMapping("/list-all-simple") | |
| 77 | + @ApiOperation(value = "获取用户组精简信息列表", notes = "只包含被开启的用户组,主要用于前端的下拉选项") | |
| 78 | + public CommonResult<List<BpmUserGroupRespVO>> getSimpleUserGroups() { | |
| 79 | + // 获用户门列表,只要开启状态的 | |
| 80 | + List<BpmUserGroupDO> list = userGroupService.getUserGroupListByStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 81 | + // 排序后,返回给前端 | |
| 82 | + return success(BpmUserGroupConvert.INSTANCE.convertList2(list)); | |
| 83 | + } | |
| 84 | + | |
| 85 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import io.swagger.annotations.*; | |
| 5 | +import javax.validation.constraints.*; | |
| 6 | + | |
| 7 | +/** | |
| 8 | +* 动态表单 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 9 | +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 10 | +*/ | |
| 11 | +@Data | |
| 12 | +public class BpmFormBaseVO { | |
| 13 | + | |
| 14 | + @ApiModelProperty(value = "表单名称", required = true, example = "芋道") | |
| 15 | + @NotNull(message = "表单名称不能为空") | |
| 16 | + private String name; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "表单状态", required = true, notes = "参见 CommonStatusEnum 枚举", example = "1") | |
| 19 | + @NotNull(message = "表单状态不能为空") | |
| 20 | + private Integer status; | |
| 21 | + | |
| 22 | + @ApiModelProperty(value = "备注", example = "我是备注") | |
| 23 | + private String remark; | |
| 24 | + | |
| 25 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import io.swagger.annotations.*; | |
| 5 | + | |
| 6 | +import javax.validation.constraints.NotNull; | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 动态表单创建 Request VO") | |
| 10 | +@Data | |
| 11 | +@EqualsAndHashCode(callSuper = true) | |
| 12 | +@ToString(callSuper = true) | |
| 13 | +public class BpmFormCreateReqVO extends BpmFormBaseVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串") | |
| 16 | + @NotNull(message = "表单的配置不能为空") | |
| 17 | + private String conf; | |
| 18 | + | |
| 19 | + @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组") | |
| 20 | + @NotNull(message = "表单项的数组不能为空") | |
| 21 | + private List<String> fields; | |
| 22 | + | |
| 23 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.annotations.ApiModel; | |
| 5 | +import io.swagger.annotations.ApiModelProperty; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.EqualsAndHashCode; | |
| 8 | +import lombok.ToString; | |
| 9 | + | |
| 10 | +@ApiModel("管理后台 - 动态表单分页 Request VO") | |
| 11 | +@Data | |
| 12 | +@EqualsAndHashCode(callSuper = true) | |
| 13 | +@ToString(callSuper = true) | |
| 14 | +public class BpmFormPageReqVO extends PageParam { | |
| 15 | + | |
| 16 | + @ApiModelProperty(value = "表单名称", example = "芋道") | |
| 17 | + private String name; | |
| 18 | + | |
| 19 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import javax.validation.constraints.NotNull; | |
| 10 | +import java.util.Date; | |
| 11 | +import java.util.List; | |
| 12 | + | |
| 13 | +@ApiModel("管理后台 - 动态表单 Response VO") | |
| 14 | +@Data | |
| 15 | +@EqualsAndHashCode(callSuper = true) | |
| 16 | +@ToString(callSuper = true) | |
| 17 | +public class BpmFormRespVO extends BpmFormBaseVO { | |
| 18 | + | |
| 19 | + @ApiModelProperty(value = "表单编号", required = true, example = "1024") | |
| 20 | + private Long id; | |
| 21 | + | |
| 22 | + @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串") | |
| 23 | + @NotNull(message = "表单的配置不能为空") | |
| 24 | + private String conf; | |
| 25 | + | |
| 26 | + @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组") | |
| 27 | + @NotNull(message = "表单项的数组不能为空") | |
| 28 | + private List<String> fields; | |
| 29 | + | |
| 30 | + @ApiModelProperty(value = "创建时间", required = true) | |
| 31 | + private Date createTime; | |
| 32 | + | |
| 33 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +@ApiModel("管理后台 - 流程表单精简 Response VO") | |
| 8 | +@Data | |
| 9 | +public class BpmFormSimpleRespVO { | |
| 10 | + | |
| 11 | + @ApiModelProperty(value = "表单编号", required = true, example = "1024") | |
| 12 | + private Long id; | |
| 13 | + | |
| 14 | + @ApiModelProperty(value = "表单名称", required = true, example = "芋道") | |
| 15 | + private String name; | |
| 16 | + | |
| 17 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import io.swagger.annotations.*; | |
| 5 | +import javax.validation.constraints.*; | |
| 6 | +import java.util.List; | |
| 7 | + | |
| 8 | +@ApiModel("管理后台 - 动态表单更新 Request VO") | |
| 9 | +@Data | |
| 10 | +@EqualsAndHashCode(callSuper = true) | |
| 11 | +@ToString(callSuper = true) | |
| 12 | +public class BpmFormUpdateReqVO extends BpmFormBaseVO { | |
| 13 | + | |
| 14 | + @ApiModelProperty(value = "表单编号", required = true, example = "1024") | |
| 15 | + @NotNull(message = "表单编号不能为空") | |
| 16 | + private Long id; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串") | |
| 19 | + @NotNull(message = "表单的配置不能为空") | |
| 20 | + private String conf; | |
| 21 | + | |
| 22 | + @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组") | |
| 23 | + @NotNull(message = "表单项的数组不能为空") | |
| 24 | + private List<String> fields; | |
| 25 | + | |
| 26 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import java.util.*; | |
| 5 | +import io.swagger.annotations.*; | |
| 6 | +import javax.validation.constraints.*; | |
| 7 | + | |
| 8 | +/** | |
| 9 | +* 用户组 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 10 | +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 11 | +*/ | |
| 12 | +@Data | |
| 13 | +public class BpmUserGroupBaseVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "组名", required = true, example = "芋道") | |
| 16 | + @NotNull(message = "组名不能为空") | |
| 17 | + private String name; | |
| 18 | + | |
| 19 | + @ApiModelProperty(value = "描述", required = true, example = "芋道源码") | |
| 20 | + @NotNull(message = "描述不能为空") | |
| 21 | + private String description; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "成员编号数组", required = true, example = "1,2,3") | |
| 24 | + @NotNull(message = "成员编号数组不能为空") | |
| 25 | + private Set<Long> memberUserIds; | |
| 26 | + | |
| 27 | + @ApiModelProperty(value = "状态", required = true, example = "1") | |
| 28 | + @NotNull(message = "状态不能为空") | |
| 29 | + private Integer status; | |
| 30 | + | |
| 31 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import io.swagger.annotations.*; | |
| 5 | + | |
| 6 | +@ApiModel("管理后台 - 用户组创建 Request VO") | |
| 7 | +@Data | |
| 8 | +@EqualsAndHashCode(callSuper = true) | |
| 9 | +@ToString(callSuper = true) | |
| 10 | +public class BpmUserGroupCreateReqVO extends BpmUserGroupBaseVO { | |
| 11 | + | |
| 12 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.date.DateUtils; | |
| 5 | +import io.swagger.annotations.ApiModel; | |
| 6 | +import io.swagger.annotations.ApiModelProperty; | |
| 7 | +import lombok.Data; | |
| 8 | +import lombok.EqualsAndHashCode; | |
| 9 | +import lombok.ToString; | |
| 10 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 11 | + | |
| 12 | +import java.util.Date; | |
| 13 | + | |
| 14 | +@ApiModel("管理后台 - 用户组分页 Request VO") | |
| 15 | +@Data | |
| 16 | +@EqualsAndHashCode(callSuper = true) | |
| 17 | +@ToString(callSuper = true) | |
| 18 | +public class BpmUserGroupPageReqVO extends PageParam { | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "组名", example = "芋道") | |
| 21 | + private String name; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "状态", example = "1") | |
| 24 | + private Integer status; | |
| 25 | + | |
| 26 | + @DateTimeFormat(pattern = DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 27 | + @ApiModelProperty(value = "开始创建时间") | |
| 28 | + private Date beginCreateTime; | |
| 29 | + | |
| 30 | + @DateTimeFormat(pattern = DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 31 | + @ApiModelProperty(value = "结束创建时间") | |
| 32 | + private Date endCreateTime; | |
| 33 | + | |
| 34 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import java.util.*; | |
| 5 | +import io.swagger.annotations.*; | |
| 6 | + | |
| 7 | +@ApiModel("管理后台 - 用户组 Response VO") | |
| 8 | +@Data | |
| 9 | +@EqualsAndHashCode(callSuper = true) | |
| 10 | +@ToString(callSuper = true) | |
| 11 | +public class BpmUserGroupRespVO extends BpmUserGroupBaseVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "编号", required = true, example = "1024") | |
| 14 | + private Long id; | |
| 15 | + | |
| 16 | + @ApiModelProperty(value = "创建时间", required = true) | |
| 17 | + private Date createTime; | |
| 18 | + | |
| 19 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.AllArgsConstructor; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.NoArgsConstructor; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 用户组精简信息 Response VO") | |
| 10 | +@Data | |
| 11 | +@NoArgsConstructor | |
| 12 | +@AllArgsConstructor | |
| 13 | +public class BpmUserGroupSimpleRespVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "用户组编号", required = true, example = "1024") | |
| 16 | + private Long id; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "用户组名字", required = true, example = "芋道") | |
| 19 | + private String name; | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import io.swagger.annotations.*; | |
| 5 | +import javax.validation.constraints.*; | |
| 6 | + | |
| 7 | +@ApiModel("管理后台 - 用户组更新 Request VO") | |
| 8 | +@Data | |
| 9 | +@EqualsAndHashCode(callSuper = true) | |
| 10 | +@ToString(callSuper = true) | |
| 11 | +public class BpmUserGroupUpdateReqVO extends BpmUserGroupBaseVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "编号", required = true, example = "1024") | |
| 14 | + @NotNull(message = "编号不能为空") | |
| 15 | + private Long id; | |
| 16 | + | |
| 17 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | +import org.springframework.web.multipart.MultipartFile; | |
| 9 | + | |
| 10 | +import javax.validation.constraints.NotNull; | |
| 11 | + | |
| 12 | +@ApiModel(value = "管理后台 - 流程模型的导入 Request VO", description = "相比流程模型的新建来说,只是多了一个 bpmnFile 文件") | |
| 13 | +@Data | |
| 14 | +@EqualsAndHashCode(callSuper = true) | |
| 15 | +@ToString(callSuper = true) | |
| 16 | +public class BpmModeImportReqVO extends BpmModelCreateReqVO { | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "BPMN 文件", required = true) | |
| 19 | + @NotNull(message = "BPMN 文件不能为空") | |
| 20 | + private MultipartFile bpmnFile; | |
| 21 | + | |
| 22 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModelProperty; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +import javax.validation.constraints.NotEmpty; | |
| 7 | + | |
| 8 | +/** | |
| 9 | +* 流程模型 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 10 | +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 11 | +*/ | |
| 12 | +@Data | |
| 13 | +public class BpmModelBaseVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "流程标识", required = true, example = "process_yudao") | |
| 16 | + @NotEmpty(message = "流程标识不能为空") | |
| 17 | + private String key; | |
| 18 | + | |
| 19 | + @ApiModelProperty(value = "流程名称", required = true, example = "芋道") | |
| 20 | + @NotEmpty(message = "流程名称不能为空") | |
| 21 | + private String name; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "流程描述", example = "我是描述") | |
| 24 | + private String description; | |
| 25 | + | |
| 26 | + @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") | |
| 27 | + @NotEmpty(message = "流程分类不能为空") | |
| 28 | + private String category; | |
| 29 | + | |
| 30 | + @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") | |
| 31 | + private Integer formType; | |
| 32 | + @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 33 | + private Long formId; | |
| 34 | + @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", | |
| 35 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 36 | + private String formCustomCreatePath; | |
| 37 | + @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", | |
| 38 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 39 | + private String formCustomViewPath; | |
| 40 | + | |
| 41 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import javax.validation.constraints.NotEmpty; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程模型的创建 Request VO") | |
| 12 | +@Data | |
| 13 | +public class BpmModelCreateReqVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "流程标识", required = true, example = "process_yudao") | |
| 16 | + @NotEmpty(message = "流程标识不能为空") | |
| 17 | + private String key; | |
| 18 | + | |
| 19 | + @ApiModelProperty(value = "流程名称", required = true, example = "芋道") | |
| 20 | + @NotEmpty(message = "流程名称不能为空") | |
| 21 | + private String name; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "流程描述", example = "我是描述") | |
| 24 | + private String description; | |
| 25 | + | |
| 26 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import java.util.Date; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程模型的分页的每一项 Response VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class BpmModelPageItemRespVO extends BpmModelBaseVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "编号", required = true, example = "1024") | |
| 18 | + private String id; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "表单名字", example = "请假表单") | |
| 21 | + private String formName; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "创建时间", required = true) | |
| 24 | + private Date createTime; | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * 最新部署的流程定义 | |
| 28 | + */ | |
| 29 | + private ProcessDefinition processDefinition; | |
| 30 | + | |
| 31 | + @ApiModel("流程定义") | |
| 32 | + @Data | |
| 33 | + public static class ProcessDefinition { | |
| 34 | + | |
| 35 | + @ApiModelProperty(value = "编号", required = true, example = "1024") | |
| 36 | + private String id; | |
| 37 | + | |
| 38 | + @ApiModelProperty(value = "版本", required = true, example = "1") | |
| 39 | + private Integer version; | |
| 40 | + | |
| 41 | + @ApiModelProperty(value = "部署时间", required = true) | |
| 42 | + private Date deploymentTime; | |
| 43 | + | |
| 44 | + @ApiModelProperty(value = "中断状态", required = true, example = "1", notes = "参见 SuspensionState 枚举") | |
| 45 | + private Integer suspensionState; | |
| 46 | + | |
| 47 | + } | |
| 48 | + | |
| 49 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.annotations.ApiModel; | |
| 5 | +import io.swagger.annotations.ApiModelProperty; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.EqualsAndHashCode; | |
| 8 | +import lombok.ToString; | |
| 9 | + | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程模型分页 Request VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class BpmModelPageReqVO extends PageParam { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "标识", example = "process1641042089407", notes = "精准匹配") | |
| 18 | + private String key; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "名字", example = "芋道", notes = "模糊匹配") | |
| 21 | + private String name; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") | |
| 24 | + private String category; | |
| 25 | + | |
| 26 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import java.util.Date; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程模型的创建 Request VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class BpmModelRespVO extends BpmModelBaseVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "编号", required = true, example = "1024") | |
| 18 | + private String id; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "BPMN XML", required = true) | |
| 21 | + private String bpmnXml; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "创建时间", required = true) | |
| 24 | + private Date createTime; | |
| 25 | + | |
| 26 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotEmpty; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 流程模型的更新 Request VO") | |
| 10 | +@Data | |
| 11 | +public class BpmModelUpdateReqVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "编号", required = true, example = "1024") | |
| 14 | + @NotEmpty(message = "编号不能为空") | |
| 15 | + private String id; | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "流程名称", example = "芋道") | |
| 18 | + private String name; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "流程描述", example = "我是描述") | |
| 21 | + private String description; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") | |
| 24 | + private String category; | |
| 25 | + | |
| 26 | + @ApiModelProperty(value = "BPMN XML", required = true) | |
| 27 | + private String bpmnXml; | |
| 28 | + | |
| 29 | + @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") | |
| 30 | + private Integer formType; | |
| 31 | + @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 32 | + private Long formId; | |
| 33 | + @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", | |
| 34 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 35 | + private String formCustomCreatePath; | |
| 36 | + @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", | |
| 37 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 38 | + private String formCustomViewPath; | |
| 39 | + | |
| 40 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotNull; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 流程模型更新状态 Request VO") | |
| 10 | +@Data | |
| 11 | +public class BpmModelUpdateStateReqVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "编号", required = true, example = "1024") | |
| 14 | + @NotNull(message = "编号不能为空") | |
| 15 | + private String id; | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SuspensionState 枚举") | |
| 18 | + @NotNull(message = "状态不能为空") | |
| 19 | + private Integer state; | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.annotations.ApiModel; | |
| 5 | +import io.swagger.annotations.ApiModelProperty; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.EqualsAndHashCode; | |
| 8 | +import lombok.ToString; | |
| 9 | + | |
| 10 | +@ApiModel("管理后台 - 流程定义列表 Request VO") | |
| 11 | +@Data | |
| 12 | +@ToString(callSuper = true) | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +public class BpmProcessDefinitionListReqVO extends PageParam { | |
| 15 | + | |
| 16 | + @ApiModelProperty(value = "中断状态", example = "1", notes = "参见 SuspensionState 枚举") | |
| 17 | + private Integer suspensionState; | |
| 18 | + | |
| 19 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import java.util.Date; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程定义的分页的每一项 Response VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class BpmProcessDefinitionPageItemRespVO extends BpmProcessDefinitionRespVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "表单名字", example = "请假表单") | |
| 18 | + private String formName; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "部署时间", required = true) | |
| 21 | + private Date deploymentTime; | |
| 22 | + | |
| 23 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.annotations.ApiModel; | |
| 5 | +import io.swagger.annotations.ApiModelProperty; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.EqualsAndHashCode; | |
| 8 | +import lombok.ToString; | |
| 9 | + | |
| 10 | +@ApiModel("管理后台 - 流程定义分页 Request VO") | |
| 11 | +@Data | |
| 12 | +@ToString(callSuper = true) | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +public class BpmProcessDefinitionPageReqVO extends PageParam { | |
| 15 | + | |
| 16 | + @ApiModelProperty(value = "标识", example = "process1641042089407", notes = "精准匹配") | |
| 17 | + private String key; | |
| 18 | + | |
| 19 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotEmpty; | |
| 8 | +import javax.validation.constraints.NotNull; | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程定义 Response VO") | |
| 12 | +@Data | |
| 13 | +public class BpmProcessDefinitionRespVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "编号", required = true, example = "1024") | |
| 16 | + private String id; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "版本", required = true, example = "1") | |
| 19 | + private Integer version; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "流程名称", required = true, example = "芋道") | |
| 22 | + @NotEmpty(message = "流程名称不能为空") | |
| 23 | + private String name; | |
| 24 | + | |
| 25 | + @ApiModelProperty(value = "流程描述", example = "我是描述") | |
| 26 | + private String description; | |
| 27 | + | |
| 28 | + @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") | |
| 29 | + @NotEmpty(message = "流程分类不能为空") | |
| 30 | + private String category; | |
| 31 | + | |
| 32 | + @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") | |
| 33 | + private Integer formType; | |
| 34 | + @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 35 | + private Long formId; | |
| 36 | + @ApiModelProperty(value = "表单的配置", required = true, | |
| 37 | + notes = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 38 | + private String formConf; | |
| 39 | + @ApiModelProperty(value = "表单项的数组", required = true, | |
| 40 | + notes = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 41 | + private List<String> formFields; | |
| 42 | + @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", | |
| 43 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 44 | + private String formCustomCreatePath; | |
| 45 | + @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", | |
| 46 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 47 | + private String formCustomViewPath; | |
| 48 | + | |
| 49 | + @ApiModelProperty(value = "中断状态", required = true, example = "1", notes = "参见 SuspensionState 枚举") | |
| 50 | + private Integer suspensionState; | |
| 51 | + | |
| 52 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModelProperty; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +import javax.validation.constraints.NotEmpty; | |
| 7 | +import javax.validation.constraints.NotNull; | |
| 8 | +import java.util.Set; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * 流程任务分配规则 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 12 | + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 13 | + */ | |
| 14 | +@Data | |
| 15 | +public class BpmTaskAssignRuleBaseVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "规则类型", required = true, example = "bpm_task_assign_rule_type") | |
| 18 | + @NotNull(message = "规则类型不能为空") | |
| 19 | + private Integer type; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "规则值数组", required = true, example = "1,2,3") | |
| 22 | + @NotNull(message = "规则值数组不能为空") | |
| 23 | + private Set<Long> options; | |
| 24 | + | |
| 25 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import javax.validation.constraints.NotEmpty; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程任务分配规则的创建 Request VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class BpmTaskAssignRuleCreateReqVO extends BpmTaskAssignRuleBaseVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "流程模型的编号", required = true, example = "1024") | |
| 18 | + @NotEmpty(message = "流程模型的编号不能为空") | |
| 19 | + private String modelId; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "流程任务定义的编号", required = true, example = "2048") | |
| 22 | + @NotEmpty(message = "流程任务定义的编号不能为空") | |
| 23 | + private String taskDefinitionKey; | |
| 24 | + | |
| 25 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 流程任务分配规则的 Response VO") | |
| 10 | +@Data | |
| 11 | +@EqualsAndHashCode(callSuper = true) | |
| 12 | +@ToString(callSuper = true) | |
| 13 | +public class BpmTaskAssignRuleRespVO extends BpmTaskAssignRuleBaseVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "任务分配规则的编号", required = true, example = "1024") | |
| 16 | + private Long id; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "流程模型的编号", required = true, example = "2048") | |
| 19 | + private String modelId; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "流程定义的编号", required = true, example = "4096") | |
| 22 | + private String processDefinitionId; | |
| 23 | + | |
| 24 | + @ApiModelProperty(value = "流程任务定义的编号", required = true, example = "2048") | |
| 25 | + private String taskDefinitionKey; | |
| 26 | + @ApiModelProperty(value = "流程任务定义的名字", required = true, example = "关注芋道") | |
| 27 | + private String taskDefinitionName; | |
| 28 | + | |
| 29 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import javax.validation.constraints.NotNull; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程任务分配规则的更新 Request VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class BpmTaskAssignRuleUpdateReqVO extends BpmTaskAssignRuleBaseVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "任务分配规则的编号", required = true, example = "1024") | |
| 18 | + @NotNull(message = "任务分配规则的编号不能为空") | |
| 19 | + private Long id; | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.http
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.oa; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveCreateReqVO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeavePageReqVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveRespVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.convert.oa.BpmOALeaveConvert; | |
| 7 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO; | |
| 8 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 9 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 10 | +import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService; | |
| 11 | +import io.swagger.annotations.Api; | |
| 12 | +import io.swagger.annotations.ApiImplicitParam; | |
| 13 | +import io.swagger.annotations.ApiOperation; | |
| 14 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 15 | +import org.springframework.validation.annotation.Validated; | |
| 16 | +import org.springframework.web.bind.annotation.*; | |
| 17 | + | |
| 18 | +import javax.annotation.Resource; | |
| 19 | +import javax.validation.Valid; | |
| 20 | + | |
| 21 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 22 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * OA 请假申请 Controller,用于演示自己存储数据,接入工作流的例子 | |
| 26 | + * | |
| 27 | + * @author jason | |
| 28 | + * @author 芋道源码 | |
| 29 | + */ | |
| 30 | +@Api(tags = "管理后台 - OA 请假申请") | |
| 31 | +@RestController | |
| 32 | +@RequestMapping("/bpm/oa/leave") | |
| 33 | +@Validated | |
| 34 | +public class BpmOALeaveController { | |
| 35 | + | |
| 36 | + @Resource | |
| 37 | + private BpmOALeaveService leaveService; | |
| 38 | + | |
| 39 | + @PostMapping("/create") | |
| 40 | + @PreAuthorize("@ss.hasPermission('bpm:oa-leave:create')") | |
| 41 | + @ApiOperation("创建请求申请") | |
| 42 | + public CommonResult<Long> createLeave(@Valid @RequestBody BpmOALeaveCreateReqVO createReqVO) { | |
| 43 | + return success(leaveService.createLeave(getLoginUserId(), createReqVO)); | |
| 44 | + } | |
| 45 | + | |
| 46 | + @GetMapping("/get") | |
| 47 | + @PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')") | |
| 48 | + @ApiOperation("获得请假申请") | |
| 49 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | |
| 50 | + public CommonResult<BpmOALeaveRespVO> getLeave(@RequestParam("id") Long id) { | |
| 51 | + BpmOALeaveDO leave = leaveService.getLeave(id); | |
| 52 | + return success(BpmOALeaveConvert.INSTANCE.convert(leave)); | |
| 53 | + } | |
| 54 | + | |
| 55 | + @GetMapping("/page") | |
| 56 | + @PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')") | |
| 57 | + @ApiOperation("获得请假申请分页") | |
| 58 | + public CommonResult<PageResult<BpmOALeaveRespVO>> getLeavePage(@Valid BpmOALeavePageReqVO pageVO) { | |
| 59 | + PageResult<BpmOALeaveDO> pageResult = leaveService.getLeavePage(getLoginUserId(), pageVO); | |
| 60 | + return success(BpmOALeaveConvert.INSTANCE.convertPage(pageResult)); | |
| 61 | + } | |
| 62 | + | |
| 63 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/package-info.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import java.util.*; | |
| 5 | +import io.swagger.annotations.*; | |
| 6 | +import javax.validation.constraints.*; | |
| 7 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 8 | + | |
| 9 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 10 | + | |
| 11 | +/** | |
| 12 | +* 请假申请 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 13 | +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 14 | +*/ | |
| 15 | +@Data | |
| 16 | +public class BpmOALeaveBaseVO { | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "请假的开始时间", required = true) | |
| 19 | + @NotNull(message = "开始时间不能为空") | |
| 20 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 21 | + private Date startTime; | |
| 22 | + @ApiModelProperty(value = "请假的结束时间", required = true) | |
| 23 | + @NotNull(message = "结束时间不能为空") | |
| 24 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 25 | + private Date endTime; | |
| 26 | + | |
| 27 | + @ApiModelProperty(value = "请假类型", required = true, example = "1", notes = "参见 bpm_oa_type 枚举") | |
| 28 | + private Integer type; | |
| 29 | + | |
| 30 | + @ApiModelProperty(value = "原因", required = true, example = "阅读芋道源码") | |
| 31 | + private String reason; | |
| 32 | + | |
| 33 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import lombok.Data; | |
| 5 | +import lombok.EqualsAndHashCode; | |
| 6 | +import lombok.ToString; | |
| 7 | + | |
| 8 | +import javax.validation.constraints.AssertTrue; | |
| 9 | + | |
| 10 | +@ApiModel("管理后台 - 请假申请创建 Request VO") | |
| 11 | +@Data | |
| 12 | +@EqualsAndHashCode(callSuper = true) | |
| 13 | +@ToString(callSuper = true) | |
| 14 | +public class BpmOALeaveCreateReqVO extends BpmOALeaveBaseVO { | |
| 15 | + | |
| 16 | + @AssertTrue(message = "结束时间,需要在开始时间之后") | |
| 17 | + public boolean isEndTimeValid() { | |
| 18 | + return !getEndTime().before(getStartTime()); | |
| 19 | + } | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import java.util.*; | |
| 5 | +import io.swagger.annotations.*; | |
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 7 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 8 | + | |
| 9 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 请假申请分页 Request VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class BpmOALeavePageReqVO extends PageParam { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "状态", example = "1", notes = "参见 bpm_process_instance_result 枚举") | |
| 18 | + private Integer result; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "请假类型", example = "1", notes = "参见 bpm_oa_type") | |
| 21 | + private Integer type; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "原因", example = "阅读芋道源码", notes = "模糊匹配") | |
| 24 | + private String reason; | |
| 25 | + | |
| 26 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 27 | + @ApiModelProperty(value = "开始申请时间") | |
| 28 | + private Date beginCreateTime; | |
| 29 | + | |
| 30 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 31 | + @ApiModelProperty(value = "结束申请时间") | |
| 32 | + private Date endCreateTime; | |
| 33 | + | |
| 34 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import io.swagger.annotations.*; | |
| 5 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotNull; | |
| 8 | +import java.util.Date; | |
| 9 | + | |
| 10 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 11 | + | |
| 12 | +@ApiModel("管理后台 - 请假申请 Response VO") | |
| 13 | +@Data | |
| 14 | +@EqualsAndHashCode(callSuper = true) | |
| 15 | +@ToString(callSuper = true) | |
| 16 | +public class BpmOALeaveRespVO extends BpmOALeaveBaseVO { | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "请假表单主键", required = true, example = "1024") | |
| 19 | + private Long id; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 bpm_process_instance_result 枚举") | |
| 22 | + private Integer result; | |
| 23 | + | |
| 24 | + @ApiModelProperty(value = "申请时间", required = true) | |
| 25 | + @NotNull(message = "申请时间不能为空") | |
| 26 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 27 | + private Date createTime; | |
| 28 | + | |
| 29 | + @ApiModelProperty(value = "流程id") | |
| 30 | + private String processInstanceId; | |
| 31 | + | |
| 32 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService; | |
| 6 | +import io.swagger.annotations.Api; | |
| 7 | +import io.swagger.annotations.ApiImplicitParam; | |
| 8 | +import io.swagger.annotations.ApiOperation; | |
| 9 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 10 | +import org.springframework.validation.annotation.Validated; | |
| 11 | +import org.springframework.web.bind.annotation.GetMapping; | |
| 12 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 13 | +import org.springframework.web.bind.annotation.RequestParam; | |
| 14 | +import org.springframework.web.bind.annotation.RestController; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | +import java.util.List; | |
| 18 | + | |
| 19 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 20 | + | |
| 21 | +@Api(tags = "管理后台 - 流程活动实例") | |
| 22 | +@RestController | |
| 23 | +@RequestMapping("/bpm/activity") | |
| 24 | +@Validated | |
| 25 | +public class BpmActivityController { | |
| 26 | + | |
| 27 | + @Resource | |
| 28 | + private BpmActivityService activityService; | |
| 29 | + | |
| 30 | + @GetMapping("/list") | |
| 31 | + @ApiOperation(value = "生成指定流程实例的高亮流程图", | |
| 32 | + notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成") | |
| 33 | + @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class) | |
| 34 | + @PreAuthorize("@ss.hasPermission('bpm:task:query')") | |
| 35 | + public CommonResult<List<BpmActivityRespVO>> getActivityList( | |
| 36 | + @RequestParam("processInstanceId") String processInstanceId) { | |
| 37 | + return success(activityService.getActivityListByProcessInstanceId(processInstanceId)); | |
| 38 | + } | |
| 39 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; | |
| 7 | +import io.swagger.annotations.Api; | |
| 8 | +import io.swagger.annotations.ApiImplicitParam; | |
| 9 | +import io.swagger.annotations.ApiOperation; | |
| 10 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 11 | +import org.springframework.validation.annotation.Validated; | |
| 12 | +import org.springframework.web.bind.annotation.*; | |
| 13 | + | |
| 14 | +import javax.annotation.Resource; | |
| 15 | +import javax.validation.Valid; | |
| 16 | + | |
| 17 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 18 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 19 | + | |
| 20 | +@Api(tags = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请” | |
| 21 | +@RestController | |
| 22 | +@RequestMapping("/bpm/process-instance") | |
| 23 | +@Validated | |
| 24 | +public class BpmProcessInstanceController { | |
| 25 | + @Resource | |
| 26 | + private BpmProcessInstanceService processInstanceService; | |
| 27 | + | |
| 28 | + @GetMapping("/my-page") | |
| 29 | + @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用") | |
| 30 | + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") | |
| 31 | + public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage( | |
| 32 | + @Valid BpmProcessInstanceMyPageReqVO pageReqVO) { | |
| 33 | + return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO)); | |
| 34 | + } | |
| 35 | + | |
| 36 | + @PostMapping("/create") | |
| 37 | + @ApiOperation("新建流程实例") | |
| 38 | + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") | |
| 39 | + public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) { | |
| 40 | + return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO)); | |
| 41 | + } | |
| 42 | + | |
| 43 | + @GetMapping("/get") | |
| 44 | + @ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用") | |
| 45 | + @ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class) | |
| 46 | + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") | |
| 47 | + public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) { | |
| 48 | + return success(processInstanceService.getProcessInstanceVO(id)); | |
| 49 | + } | |
| 50 | + | |
| 51 | + @DeleteMapping("/cancel") | |
| 52 | + @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程") | |
| 53 | + @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')") | |
| 54 | + public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) { | |
| 55 | + processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO); | |
| 56 | + return success(true); | |
| 57 | + } | |
| 58 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; | |
| 7 | +import io.swagger.annotations.Api; | |
| 8 | +import io.swagger.annotations.ApiImplicitParam; | |
| 9 | +import io.swagger.annotations.ApiOperation; | |
| 10 | +import org.flowable.bpmn.model.BpmnModel; | |
| 11 | +import org.flowable.engine.TaskService; | |
| 12 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 13 | +import org.springframework.validation.annotation.Validated; | |
| 14 | +import org.springframework.web.bind.annotation.*; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | +import javax.validation.Valid; | |
| 18 | + | |
| 19 | +import java.util.List; | |
| 20 | + | |
| 21 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 22 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; | |
| 23 | + | |
| 24 | +@Api(tags = "管理后台 - 流程任务实例") | |
| 25 | +@RestController | |
| 26 | +@RequestMapping("/bpm/task") | |
| 27 | +@Validated | |
| 28 | +public class BpmTaskController { | |
| 29 | + | |
| 30 | + @Resource | |
| 31 | + private BpmTaskService taskService; | |
| 32 | + | |
| 33 | + @GetMapping("todo-page") | |
| 34 | + @ApiOperation("获取 Todo 待办任务分页") | |
| 35 | + @PreAuthorize("@ss.hasPermission('bpm:task:query')") | |
| 36 | + public CommonResult<PageResult<BpmTaskTodoPageItemRespVO>> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) { | |
| 37 | + return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO)); | |
| 38 | + } | |
| 39 | + | |
| 40 | + @GetMapping("done-page") | |
| 41 | + @ApiOperation("获取 Done 已办任务分页") | |
| 42 | + @PreAuthorize("@ss.hasPermission('bpm:task:query')") | |
| 43 | + public CommonResult<PageResult<BpmTaskDonePageItemRespVO>> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) { | |
| 44 | + return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO)); | |
| 45 | + } | |
| 46 | + | |
| 47 | + @GetMapping("/list-by-process-instance-id") | |
| 48 | + @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的") | |
| 49 | + @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class) | |
| 50 | + @PreAuthorize("@ss.hasPermission('bpm:task:query')") | |
| 51 | + public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId( | |
| 52 | + @RequestParam("processInstanceId") String processInstanceId) { | |
| 53 | + return success(taskService.getTaskListByProcessInstanceId(processInstanceId)); | |
| 54 | + } | |
| 55 | + | |
| 56 | + @PutMapping("/approve") | |
| 57 | + @ApiOperation("通过任务") | |
| 58 | + @PreAuthorize("@ss.hasPermission('bpm:task:update')") | |
| 59 | + public CommonResult<Boolean> approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) { | |
| 60 | + taskService.approveTask(getLoginUserId(), reqVO); | |
| 61 | + return success(true); | |
| 62 | + } | |
| 63 | + | |
| 64 | + @PutMapping("/reject") | |
| 65 | + @ApiOperation("不通过任务") | |
| 66 | + @PreAuthorize("@ss.hasPermission('bpm:task:update')") | |
| 67 | + public CommonResult<Boolean> rejectTask(@Valid @RequestBody BpmTaskRejectReqVO reqVO) { | |
| 68 | + taskService.rejectTask(getLoginUserId(), reqVO); | |
| 69 | + return success(true); | |
| 70 | + } | |
| 71 | + | |
| 72 | + @PutMapping("/update-assignee") | |
| 73 | + @ApiOperation(value = "更新任务的负责人", notes = "用于【流程详情】的【转派】按钮") | |
| 74 | + @PreAuthorize("@ss.hasPermission('bpm:task:update')") | |
| 75 | + public CommonResult<Boolean> updateTaskAssignee(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) { | |
| 76 | + taskService.updateTaskAssignee(getLoginUserId(), reqVO); | |
| 77 | + return success(true); | |
| 78 | + } | |
| 79 | + @PutMapping("/back") | |
| 80 | + @ApiOperation(value = "回退") | |
| 81 | +// @PreAuthorize("@ss.hasPermission('bpm:task:back')") | |
| 82 | + public CommonResult<Boolean> backTask(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) { | |
| 83 | + //先硬编码到 回退到第一个审批节点 | |
| 84 | + String destinationTaskDefKey = "task01"; | |
| 85 | + taskService.backTask(reqVO.getId(),destinationTaskDefKey); | |
| 86 | + return success(true); | |
| 87 | + } | |
| 88 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task; | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import java.util.Date; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 流程活动的 Response VO") | |
| 10 | +@Data | |
| 11 | +public class BpmActivityRespVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "流程活动的标识", required = true, example = "1024") | |
| 14 | + private String key; | |
| 15 | + @ApiModelProperty(value = "流程活动的类型", required = true, example = "StartEvent") | |
| 16 | + private String type; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "流程活动的开始时间", required = true) | |
| 19 | + private Date startTime; | |
| 20 | + @ApiModelProperty(value = "流程活动的结束时间", required = true) | |
| 21 | + private Date endTime; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "关联的流程任务的编号", example = "2048", notes = "关联的流程任务,只有 UserTask 等类型才有") | |
| 24 | + private String taskId; | |
| 25 | + | |
| 26 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotEmpty; | |
| 8 | +import javax.validation.constraints.NotNull; | |
| 9 | +import java.util.Map; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程实例的取消 Request VO") | |
| 12 | +@Data | |
| 13 | +public class BpmProcessInstanceCancelReqVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "流程实例的编号", required = true, example = "1024") | |
| 16 | + @NotEmpty(message = "流程实例的编号不能为空") | |
| 17 | + private String id; | |
| 18 | + | |
| 19 | + @ApiModelProperty(value = "取消原因", required = true, example = "不请假了!") | |
| 20 | + @NotEmpty(message = "取消原因不能为空") | |
| 21 | + private String reason; | |
| 22 | + | |
| 23 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotEmpty; | |
| 8 | +import java.util.Map; | |
| 9 | + | |
| 10 | +@ApiModel("管理后台 - 流程实例的创建 Request VO") | |
| 11 | +@Data | |
| 12 | +public class BpmProcessInstanceCreateReqVO { | |
| 13 | + | |
| 14 | + @ApiModelProperty(value = "流程定义的编号", required = true, example = "1024") | |
| 15 | + @NotEmpty(message = "流程定义编号不能为空") | |
| 16 | + private String processDefinitionId; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "变量实例") | |
| 19 | + private Map<String, Object> variables; | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.annotations.ApiModel; | |
| 5 | +import io.swagger.annotations.ApiModelProperty; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.EqualsAndHashCode; | |
| 8 | +import lombok.ToString; | |
| 9 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 10 | + | |
| 11 | +import java.util.Date; | |
| 12 | + | |
| 13 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 14 | + | |
| 15 | +@ApiModel("管理后台 - 流程实例的分页 Item Response VO") | |
| 16 | +@Data | |
| 17 | +@EqualsAndHashCode(callSuper = true) | |
| 18 | +@ToString(callSuper = true) | |
| 19 | +public class BpmProcessInstanceMyPageReqVO extends PageParam { | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "流程名称", example = "芋道") | |
| 22 | + private String name; | |
| 23 | + | |
| 24 | + @ApiModelProperty(value = "流程定义的编号", example = "2048") | |
| 25 | + private String processDefinitionId; | |
| 26 | + | |
| 27 | + @ApiModelProperty(value = "流程实例的状态", notes = "参见 bpm_process_instance_status", example = "1") | |
| 28 | + private Integer status; | |
| 29 | + | |
| 30 | + @ApiModelProperty(value = "流程实例的结果", notes = "参见 bpm_process_instance_result", example = "2") | |
| 31 | + private Integer result; | |
| 32 | + | |
| 33 | + @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") | |
| 34 | + private String category; | |
| 35 | + | |
| 36 | + @ApiModelProperty(value = "开始的创建时间") | |
| 37 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 38 | + private Date beginCreateTime; | |
| 39 | + | |
| 40 | + @ApiModelProperty(value = "结束的创建时间") | |
| 41 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 42 | + private Date endCreateTime; | |
| 43 | + | |
| 44 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import java.util.Date; | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +@ApiModel("管理后台 - 流程实例的分页 Item Response VO") | |
| 11 | +@Data | |
| 12 | +public class BpmProcessInstancePageItemRespVO { | |
| 13 | + | |
| 14 | + @ApiModelProperty(value = "流程实例的编号", required = true, example = "1024") | |
| 15 | + private String id; | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "流程名称", required = true, example = "芋道") | |
| 18 | + private String name; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "流程定义的编号", required = true, example = "2048") | |
| 21 | + private String processDefinitionId; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "流程分类", required = true, notes = "参见 bpm_model_category 数据字典", example = "1") | |
| 24 | + private String category; | |
| 25 | + | |
| 26 | + @ApiModelProperty(value = "流程实例的状态", required = true, notes = "参见 bpm_process_instance_status", example = "1") | |
| 27 | + private Integer status; | |
| 28 | + | |
| 29 | + @ApiModelProperty(value = "流程实例的结果", required = true, notes = "参见 bpm_process_instance_result", example = "2") | |
| 30 | + private Integer result; | |
| 31 | + | |
| 32 | + @ApiModelProperty(value = "提交时间", required = true) | |
| 33 | + private Date createTime; | |
| 34 | + | |
| 35 | + @ApiModelProperty(value = "结束时间", required = true) | |
| 36 | + private Date endTime; | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * 当前任务 | |
| 40 | + */ | |
| 41 | + private List<Task> tasks; | |
| 42 | + | |
| 43 | + @ApiModel("流程任务") | |
| 44 | + @Data | |
| 45 | + public static class Task { | |
| 46 | + | |
| 47 | + @ApiModelProperty(value = "流程任务的编号", required = true, example = "1024") | |
| 48 | + private String id; | |
| 49 | + | |
| 50 | + @ApiModelProperty(value = "任务名称", required = true, example = "芋道") | |
| 51 | + private String name; | |
| 52 | + | |
| 53 | + } | |
| 54 | + | |
| 55 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import java.util.Date; | |
| 8 | +import java.util.List; | |
| 9 | +import java.util.Map; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程实例的 Response VO") | |
| 12 | +@Data | |
| 13 | +public class BpmProcessInstanceRespVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "流程实例的编号", required = true, example = "1024") | |
| 16 | + private String id; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "流程名称", required = true, example = "芋道") | |
| 19 | + private String name; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "流程分类", required = true, notes = "参见 bpm_model_category 数据字典", example = "1") | |
| 22 | + private String category; | |
| 23 | + | |
| 24 | + @ApiModelProperty(value = "流程实例的状态", required = true, notes = "参见 bpm_process_instance_status", example = "1") | |
| 25 | + private Integer status; | |
| 26 | + | |
| 27 | + @ApiModelProperty(value = "流程实例的结果", required = true, notes = "参见 bpm_process_instance_result", example = "2") | |
| 28 | + private Integer result; | |
| 29 | + | |
| 30 | + @ApiModelProperty(value = "提交时间", required = true) | |
| 31 | + private Date createTime; | |
| 32 | + | |
| 33 | + @ApiModelProperty(value = "结束时间", required = true) | |
| 34 | + private Date endTime; | |
| 35 | + | |
| 36 | + @ApiModelProperty(value = "提交的表单值", required = true) | |
| 37 | + private Map<String, Object> formVariables; | |
| 38 | + | |
| 39 | + @ApiModelProperty(value = "业务的唯一标识", example = "1", notes = "例如说,请假申请的编号") | |
| 40 | + private String businessKey; | |
| 41 | + | |
| 42 | + /** | |
| 43 | + * 发起流程的用户 | |
| 44 | + */ | |
| 45 | + private User startUser; | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * 流程定义 | |
| 49 | + */ | |
| 50 | + private ProcessDefinition processDefinition; | |
| 51 | + | |
| 52 | + @ApiModel("用户信息") | |
| 53 | + @Data | |
| 54 | + public static class User { | |
| 55 | + | |
| 56 | + @ApiModelProperty(value = "用户编号", required = true, example = "1") | |
| 57 | + private Long id; | |
| 58 | + @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") | |
| 59 | + private String nickname; | |
| 60 | + | |
| 61 | + @ApiModelProperty(value = "部门编号", required = true, example = "1") | |
| 62 | + private Long deptId; | |
| 63 | + @ApiModelProperty(value = "部门名称", required = true, example = "研发部") | |
| 64 | + private String deptName; | |
| 65 | + | |
| 66 | + } | |
| 67 | + | |
| 68 | + @ApiModel("流程定义信息") | |
| 69 | + @Data | |
| 70 | + public static class ProcessDefinition { | |
| 71 | + | |
| 72 | + @ApiModelProperty(value = "编号", required = true, example = "1024") | |
| 73 | + private String id; | |
| 74 | + | |
| 75 | + @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") | |
| 76 | + private Integer formType; | |
| 77 | + @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 78 | + private Long formId; | |
| 79 | + @ApiModelProperty(value = "表单的配置", required = true, | |
| 80 | + notes = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 81 | + private String formConf; | |
| 82 | + @ApiModelProperty(value = "表单项的数组", required = true, | |
| 83 | + notes = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 84 | + private List<String> formFields; | |
| 85 | + @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", | |
| 86 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 87 | + private String formCustomCreatePath; | |
| 88 | + @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", | |
| 89 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 90 | + private String formCustomViewPath; | |
| 91 | + | |
| 92 | + @ApiModelProperty(value = "BPMN XML", required = true) | |
| 93 | + private String bpmnXml; | |
| 94 | + | |
| 95 | + } | |
| 96 | + | |
| 97 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import javax.validation.constraints.NotEmpty; | |
| 10 | +import javax.validation.constraints.NotNull; | |
| 11 | +import java.util.Map; | |
| 12 | + | |
| 13 | +@ApiModel("管理后台 - 通过流程任务的 Request VO") | |
| 14 | +@Data | |
| 15 | +public class BpmTaskApproveReqVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "任务编号", required = true, example = "1024") | |
| 18 | + @NotEmpty(message = "任务编号不能为空") | |
| 19 | + private String id; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "审批意见", required = true, example = "不错不错!") | |
| 22 | + @NotEmpty(message = "审批意见不能为空") | |
| 23 | + private String comment; | |
| 24 | + | |
| 25 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import java.util.Date; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 流程任务的 Done 已完成的分页项 Response VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class BpmTaskDonePageItemRespVO extends BpmTaskTodoPageItemRespVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "结束时间", required = true) | |
| 18 | + private Date endTime; | |
| 19 | + @ApiModelProperty(value = "持续时间", required = true, example = "1000") | |
| 20 | + private Long durationInMillis; | |
| 21 | + | |
| 22 | + @ApiModelProperty(value = "任务结果", required = true, notes = "参见 bpm_process_instance_result", example = "2") | |
| 23 | + private Integer result; | |
| 24 | + @ApiModelProperty(value = "审批建议", required = true, example = "不请假了!") | |
| 25 | + private String comment; | |
| 26 | + | |
| 27 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.annotations.ApiModel; | |
| 5 | +import io.swagger.annotations.ApiModelProperty; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.EqualsAndHashCode; | |
| 8 | +import lombok.ToString; | |
| 9 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 10 | + | |
| 11 | +import java.util.Date; | |
| 12 | + | |
| 13 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 14 | + | |
| 15 | +@ApiModel("管理后台 - 流程任务的 Done 已办的分页 Request VO") | |
| 16 | +@Data | |
| 17 | +@EqualsAndHashCode(callSuper = true) | |
| 18 | +@ToString(callSuper = true) | |
| 19 | +public class BpmTaskDonePageReqVO extends PageParam { | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "流程任务名", example = "芋道") | |
| 22 | + private String name; | |
| 23 | + | |
| 24 | + @ApiModelProperty(value = "开始的创建收间") | |
| 25 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 26 | + private Date beginCreateTime; | |
| 27 | + | |
| 28 | + @ApiModelProperty(value = "结束的创建时间") | |
| 29 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 30 | + private Date endCreateTime; | |
| 31 | + | |
| 32 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotEmpty; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 不通过流程任务的 Request VO") | |
| 10 | +@Data | |
| 11 | +public class BpmTaskRejectReqVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "任务编号", required = true, example = "1024") | |
| 14 | + @NotEmpty(message = "任务编号不能为空") | |
| 15 | + private String id; | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "审批意见", required = true, example = "不错不错!") | |
| 18 | + @NotEmpty(message = "审批意见不能为空") | |
| 19 | + private String comment; | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 流程任务的 Response VO") | |
| 10 | +@Data | |
| 11 | +@EqualsAndHashCode(callSuper = true) | |
| 12 | +@ToString(callSuper = true) | |
| 13 | +public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "任务定义的标识", required = true, example = "user-001") | |
| 16 | + private String definitionKey; | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * 审核的用户信息 | |
| 20 | + */ | |
| 21 | + private User assigneeUser; | |
| 22 | + | |
| 23 | + @ApiModel("用户信息") | |
| 24 | + @Data | |
| 25 | + public static class User { | |
| 26 | + | |
| 27 | + @ApiModelProperty(value = "用户编号", required = true, example = "1") | |
| 28 | + private Long id; | |
| 29 | + @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") | |
| 30 | + private String nickname; | |
| 31 | + | |
| 32 | + @ApiModelProperty(value = "部门编号", required = true, example = "1") | |
| 33 | + private Long deptId; | |
| 34 | + @ApiModelProperty(value = "部门名称", required = true, example = "研发部") | |
| 35 | + private String deptName; | |
| 36 | + | |
| 37 | + } | |
| 38 | + | |
| 39 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import java.util.Date; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 流程任务的 Running 进行中的分页项 Response VO") | |
| 10 | +@Data | |
| 11 | +public class BpmTaskTodoPageItemRespVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "任务编号", required = true, example = "1024") | |
| 14 | + private String id; | |
| 15 | + | |
| 16 | + @ApiModelProperty(value = "任务名字", required = true, example = "芋道") | |
| 17 | + private String name; | |
| 18 | + | |
| 19 | + @ApiModelProperty(value = "接收时间", required = true) | |
| 20 | + private Date claimTime; | |
| 21 | + | |
| 22 | + @ApiModelProperty(value = "创建时间", required = true) | |
| 23 | + private Date createTime; | |
| 24 | + | |
| 25 | + @ApiModelProperty(value = "激活状态", required = true, example = "1", notes = "参见 SuspensionState 枚举") | |
| 26 | + private Integer suspensionState; | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 所属流程实例 | |
| 30 | + */ | |
| 31 | + private ProcessInstance processInstance; | |
| 32 | + | |
| 33 | + @Data | |
| 34 | + @ApiModel("流程实例") | |
| 35 | + public static class ProcessInstance { | |
| 36 | + | |
| 37 | + @ApiModelProperty(value = "流程实例编号", required = true, example = "1024") | |
| 38 | + private String id; | |
| 39 | + | |
| 40 | + @ApiModelProperty(value = "流程实例名称", required = true, example = "芋道") | |
| 41 | + private String name; | |
| 42 | + | |
| 43 | + @ApiModelProperty(value = "发起人的用户编号", required = true, example = "1024") | |
| 44 | + private Long startUserId; | |
| 45 | + | |
| 46 | + @ApiModelProperty(value = "发起人的用户昵称", required = true, example = "芋艿") | |
| 47 | + private String startUserNickname; | |
| 48 | + | |
| 49 | + @ApiModelProperty(value = "流程定义的编号", required = true, example = "2048") | |
| 50 | + private String processDefinitionId; | |
| 51 | + | |
| 52 | + } | |
| 53 | + | |
| 54 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.annotations.ApiModel; | |
| 5 | +import io.swagger.annotations.ApiModelProperty; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.EqualsAndHashCode; | |
| 8 | +import lombok.ToString; | |
| 9 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 10 | + | |
| 11 | +import java.util.Date; | |
| 12 | + | |
| 13 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 14 | + | |
| 15 | +@ApiModel("管理后台 - 流程任务的 TODO 待办的分页 Request VO") | |
| 16 | +@Data | |
| 17 | +@EqualsAndHashCode(callSuper = true) | |
| 18 | +@ToString(callSuper = true) | |
| 19 | +public class BpmTaskTodoPageReqVO extends PageParam { | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "流程任务名", example = "芋道") | |
| 22 | + private String name; | |
| 23 | + | |
| 24 | + @ApiModelProperty(value = "开始的创建收间") | |
| 25 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 26 | + private Date beginCreateTime; | |
| 27 | + | |
| 28 | + @ApiModelProperty(value = "结束的创建时间") | |
| 29 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 30 | + private Date endCreateTime; | |
| 31 | + | |
| 32 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | +import net.bytebuddy.implementation.bind.annotation.Empty; | |
| 9 | + | |
| 10 | +import javax.validation.constraints.NotEmpty; | |
| 11 | +import javax.validation.constraints.NotNull; | |
| 12 | + | |
| 13 | +@ApiModel("管理后台 - 流程任务的更新负责人的 Request VO") | |
| 14 | +@Data | |
| 15 | +public class BpmTaskUpdateAssigneeReqVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "任务编号", required = true, example = "1024") | |
| 18 | + @NotEmpty(message = "任务编号不能为空") | |
| 19 | + private String id; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "新审批人的用户编号", required = true, example = "2048") | |
| 22 | + @NotNull(message = "新审批人的用户编号不能为空") | |
| 23 | + private Long assigneeUserId; | |
| 24 | + | |
| 25 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmFormConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormRespVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSimpleRespVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 8 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 9 | +import org.mapstruct.Mapper; | |
| 10 | +import org.mapstruct.factory.Mappers; | |
| 11 | + | |
| 12 | +import java.util.List; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * 动态表单 Convert | |
| 16 | + * | |
| 17 | + * @author 芋艿 | |
| 18 | + */ | |
| 19 | +@Mapper | |
| 20 | +public interface BpmFormConvert { | |
| 21 | + | |
| 22 | + BpmFormConvert INSTANCE = Mappers.getMapper(BpmFormConvert.class); | |
| 23 | + | |
| 24 | + BpmFormDO convert(BpmFormCreateReqVO bean); | |
| 25 | + | |
| 26 | + BpmFormDO convert(BpmFormUpdateReqVO bean); | |
| 27 | + | |
| 28 | + BpmFormRespVO convert(BpmFormDO bean); | |
| 29 | + | |
| 30 | + List<BpmFormSimpleRespVO> convertList2(List<BpmFormDO> list); | |
| 31 | + | |
| 32 | + PageResult<BpmFormRespVO> convertPage(PageResult<BpmFormDO> page); | |
| 33 | + | |
| 34 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.definition; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; | |
| 7 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; | |
| 10 | +import org.flowable.common.engine.impl.db.SuspensionState; | |
| 11 | +import org.flowable.engine.repository.Deployment; | |
| 12 | +import org.flowable.engine.repository.Model; | |
| 13 | +import org.flowable.engine.repository.ProcessDefinition; | |
| 14 | +import org.mapstruct.Mapper; | |
| 15 | +import org.mapstruct.MappingTarget; | |
| 16 | +import org.mapstruct.factory.Mappers; | |
| 17 | + | |
| 18 | +import java.util.List; | |
| 19 | +import java.util.Map; | |
| 20 | +import java.util.Objects; | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * 流程模型 Convert | |
| 24 | + * | |
| 25 | + * @author yunlongn | |
| 26 | + */ | |
| 27 | +@Mapper | |
| 28 | +public interface BpmModelConvert { | |
| 29 | + | |
| 30 | + BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class); | |
| 31 | + | |
| 32 | + default List<BpmModelPageItemRespVO> convertList(List<Model> list, Map<Long, BpmFormDO> formMap, | |
| 33 | + Map<String, Deployment> deploymentMap, | |
| 34 | + Map<String, ProcessDefinition> processDefinitionMap) { | |
| 35 | + return CollectionUtils.convertList(list, model -> { | |
| 36 | + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); | |
| 37 | + BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null; | |
| 38 | + Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null; | |
| 39 | + ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null; | |
| 40 | + return convert(model, form, deployment, processDefinition); | |
| 41 | + }); | |
| 42 | + } | |
| 43 | + | |
| 44 | + default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) { | |
| 45 | + BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO(); | |
| 46 | + modelRespVO.setId(model.getId()); | |
| 47 | + modelRespVO.setCreateTime(model.getCreateTime()); | |
| 48 | + // 通用 copy | |
| 49 | + copyTo(model, modelRespVO); | |
| 50 | + // Form | |
| 51 | + if (form != null) { | |
| 52 | + modelRespVO.setFormId(form.getId()); | |
| 53 | + modelRespVO.setFormName(form.getName()); | |
| 54 | + } | |
| 55 | + // ProcessDefinition | |
| 56 | + modelRespVO.setProcessDefinition(this.convert(processDefinition)); | |
| 57 | + if (modelRespVO.getProcessDefinition() != null) { | |
| 58 | + modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ? | |
| 59 | + SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode()); | |
| 60 | + modelRespVO.getProcessDefinition().setDeploymentTime(deployment.getDeploymentTime()); | |
| 61 | + } | |
| 62 | + return modelRespVO; | |
| 63 | + } | |
| 64 | + | |
| 65 | + default BpmModelRespVO convert(Model model) { | |
| 66 | + BpmModelRespVO modelRespVO = new BpmModelRespVO(); | |
| 67 | + modelRespVO.setId(model.getId()); | |
| 68 | + modelRespVO.setCreateTime(model.getCreateTime()); | |
| 69 | + // 通用 copy | |
| 70 | + copyTo(model, modelRespVO); | |
| 71 | + return modelRespVO; | |
| 72 | + } | |
| 73 | + | |
| 74 | + default void copyTo(Model model, BpmModelBaseVO to) { | |
| 75 | + to.setName(model.getName()); | |
| 76 | + to.setKey(model.getKey()); | |
| 77 | + to.setCategory(model.getCategory()); | |
| 78 | + // metaInfo | |
| 79 | + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); | |
| 80 | + copyTo(metaInfo, to); | |
| 81 | + } | |
| 82 | + | |
| 83 | + BpmModelCreateReqVO convert(BpmModeImportReqVO bean); | |
| 84 | + | |
| 85 | + default BpmProcessDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) { | |
| 86 | + BpmProcessDefinitionCreateReqDTO createReqDTO = new BpmProcessDefinitionCreateReqDTO(); | |
| 87 | + createReqDTO.setModelId(model.getId()); | |
| 88 | + createReqDTO.setName(model.getName()); | |
| 89 | + createReqDTO.setKey(model.getKey()); | |
| 90 | + createReqDTO.setCategory(model.getCategory()); | |
| 91 | + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); | |
| 92 | + // metaInfo | |
| 93 | + copyTo(metaInfo, createReqDTO); | |
| 94 | + // form | |
| 95 | + if (form != null) { | |
| 96 | + createReqDTO.setFormConf(form.getConf()); | |
| 97 | + createReqDTO.setFormFields(form.getFields()); | |
| 98 | + } | |
| 99 | + return createReqDTO; | |
| 100 | + } | |
| 101 | + | |
| 102 | + void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmProcessDefinitionCreateReqDTO to); | |
| 103 | + | |
| 104 | + void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to); | |
| 105 | + | |
| 106 | + BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean); | |
| 107 | + | |
| 108 | + default void copy(Model model, BpmModelCreateReqVO bean) { | |
| 109 | + model.setName(bean.getName()); | |
| 110 | + model.setKey(bean.getKey()); | |
| 111 | + model.setMetaInfo(buildMetaInfoStr(null, bean.getDescription(), null, null, | |
| 112 | + null, null)); | |
| 113 | + } | |
| 114 | + | |
| 115 | + default void copy(Model model, BpmModelUpdateReqVO bean) { | |
| 116 | + model.setName(bean.getName()); | |
| 117 | + model.setCategory(bean.getCategory()); | |
| 118 | + model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class), | |
| 119 | + bean.getDescription(), bean.getFormType(), bean.getFormId(), | |
| 120 | + bean.getFormCustomCreatePath(), bean.getFormCustomViewPath())); | |
| 121 | + } | |
| 122 | + | |
| 123 | + default String buildMetaInfoStr(BpmModelMetaInfoRespDTO metaInfo, String description, Integer formType, | |
| 124 | + Long formId, String formCustomCreatePath, String formCustomViewPath) { | |
| 125 | + if (metaInfo == null) { | |
| 126 | + metaInfo = new BpmModelMetaInfoRespDTO(); | |
| 127 | + } | |
| 128 | + // 只有非空,才进行设置,避免更新时的覆盖 | |
| 129 | + if (StrUtil.isNotEmpty(description)) { | |
| 130 | + metaInfo.setDescription(description); | |
| 131 | + } | |
| 132 | + if (Objects.nonNull(formType)) { | |
| 133 | + metaInfo.setFormType(formType); | |
| 134 | + metaInfo.setFormId(formId); | |
| 135 | + metaInfo.setFormCustomCreatePath(formCustomCreatePath); | |
| 136 | + metaInfo.setFormCustomViewPath(formCustomViewPath); | |
| 137 | + } | |
| 138 | + return JsonUtils.toJsonString(metaInfo); | |
| 139 | + } | |
| 140 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; | |
| 9 | +import org.flowable.common.engine.impl.db.SuspensionState; | |
| 10 | +import org.flowable.engine.repository.Deployment; | |
| 11 | +import org.flowable.engine.repository.ProcessDefinition; | |
| 12 | +import org.mapstruct.Mapper; | |
| 13 | +import org.mapstruct.Mapping; | |
| 14 | +import org.mapstruct.MappingTarget; | |
| 15 | +import org.mapstruct.Named; | |
| 16 | +import org.mapstruct.factory.Mappers; | |
| 17 | + | |
| 18 | +import java.util.List; | |
| 19 | +import java.util.Map; | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * Bpm 流程定义的 Convert | |
| 23 | + * | |
| 24 | + * @author yunlong.li | |
| 25 | + */ | |
| 26 | +@Mapper | |
| 27 | +public interface BpmProcessDefinitionConvert { | |
| 28 | + | |
| 29 | + BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class); | |
| 30 | + | |
| 31 | + BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean); | |
| 32 | + | |
| 33 | + BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean); | |
| 34 | + | |
| 35 | + default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap, | |
| 36 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) { | |
| 37 | + return CollectionUtils.convertList(list, definition -> { | |
| 38 | + Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null; | |
| 39 | + BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId()); | |
| 40 | + BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null; | |
| 41 | + return convert(definition, deployment, definitionDO, form); | |
| 42 | + }); | |
| 43 | + } | |
| 44 | + | |
| 45 | + default List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list, | |
| 46 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap) { | |
| 47 | + return CollectionUtils.convertList(list, processDefinition -> { | |
| 48 | + BpmProcessDefinitionRespVO respVO = convert3(processDefinition); | |
| 49 | + BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId()); | |
| 50 | + // 复制通用属性 | |
| 51 | + copyTo(processDefinitionExtDO, respVO); | |
| 52 | + return respVO; | |
| 53 | + }); | |
| 54 | + } | |
| 55 | + | |
| 56 | + @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState") | |
| 57 | + BpmProcessDefinitionRespVO convert3(ProcessDefinition bean); | |
| 58 | + | |
| 59 | + @Named("convertSuspendedToSuspensionState") | |
| 60 | + default Integer convertSuspendedToSuspensionState(boolean suspended) { | |
| 61 | + return suspended ? SuspensionState.SUSPENDED.getStateCode() : | |
| 62 | + SuspensionState.ACTIVE.getStateCode(); | |
| 63 | + } | |
| 64 | + | |
| 65 | + default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment, | |
| 66 | + BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) { | |
| 67 | + BpmProcessDefinitionPageItemRespVO respVO = convert(bean); | |
| 68 | + respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode()); | |
| 69 | + if (deployment != null) { | |
| 70 | + respVO.setDeploymentTime(deployment.getDeploymentTime()); | |
| 71 | + } | |
| 72 | + if (form != null) { | |
| 73 | + respVO.setFormName(form.getName()); | |
| 74 | + } | |
| 75 | + // 复制通用属性 | |
| 76 | + copyTo(processDefinitionExtDO, respVO); | |
| 77 | + return respVO; | |
| 78 | + } | |
| 79 | + | |
| 80 | + @Mapping(source = "from.id", target = "to.id", ignore = true) | |
| 81 | + void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessDefinitionRespVO to); | |
| 82 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; | |
| 8 | +import org.flowable.bpmn.model.UserTask; | |
| 9 | +import org.mapstruct.Mapper; | |
| 10 | +import org.mapstruct.factory.Mappers; | |
| 11 | + | |
| 12 | +import java.util.List; | |
| 13 | +import java.util.Map; | |
| 14 | + | |
| 15 | +@Mapper | |
| 16 | +public interface BpmTaskAssignRuleConvert { | |
| 17 | + BpmTaskAssignRuleConvert INSTANCE = Mappers.getMapper(BpmTaskAssignRuleConvert.class); | |
| 18 | + | |
| 19 | + default List<BpmTaskAssignRuleRespVO> convertList(List<UserTask> tasks, List<BpmTaskAssignRuleDO> rules) { | |
| 20 | + Map<String, BpmTaskAssignRuleDO> ruleMap = CollectionUtils.convertMap(rules, BpmTaskAssignRuleDO::getTaskDefinitionKey); | |
| 21 | + // 以 UserTask 为主维度,原因是:流程图编辑后,一些规则实际就没用了。 | |
| 22 | + return CollectionUtils.convertList(tasks, task -> { | |
| 23 | + BpmTaskAssignRuleRespVO respVO = convert(ruleMap.get(task.getId())); | |
| 24 | + if (respVO == null) { | |
| 25 | + respVO = new BpmTaskAssignRuleRespVO(); | |
| 26 | + respVO.setTaskDefinitionKey(task.getId()); | |
| 27 | + } | |
| 28 | + respVO.setTaskDefinitionName(task.getName()); | |
| 29 | + return respVO; | |
| 30 | + }); | |
| 31 | + } | |
| 32 | + | |
| 33 | + BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean); | |
| 34 | + | |
| 35 | + BpmTaskAssignRuleDO convert(BpmTaskAssignRuleCreateReqVO bean); | |
| 36 | + | |
| 37 | + BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean); | |
| 38 | + | |
| 39 | + List<BpmTaskAssignRuleDO> convertList2(List<BpmTaskAssignRuleRespVO> list); | |
| 40 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmUserGroupConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.definition; | |
| 2 | + | |
| 3 | +import java.util.*; | |
| 4 | + | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupRespVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | |
| 9 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 10 | + | |
| 11 | +import org.mapstruct.Mapper; | |
| 12 | +import org.mapstruct.Named; | |
| 13 | +import org.mapstruct.factory.Mappers; | |
| 14 | + | |
| 15 | +/** | |
| 16 | + * 用户组 Convert | |
| 17 | + * | |
| 18 | + * @author 芋道源码 | |
| 19 | + */ | |
| 20 | +@Mapper | |
| 21 | +public interface BpmUserGroupConvert { | |
| 22 | + | |
| 23 | + BpmUserGroupConvert INSTANCE = Mappers.getMapper(BpmUserGroupConvert.class); | |
| 24 | + | |
| 25 | + BpmUserGroupDO convert(BpmUserGroupCreateReqVO bean); | |
| 26 | + | |
| 27 | + BpmUserGroupDO convert(BpmUserGroupUpdateReqVO bean); | |
| 28 | + | |
| 29 | + BpmUserGroupRespVO convert(BpmUserGroupDO bean); | |
| 30 | + | |
| 31 | + List<BpmUserGroupRespVO> convertList(List<BpmUserGroupDO> list); | |
| 32 | + | |
| 33 | + PageResult<BpmUserGroupRespVO> convertPage(PageResult<BpmUserGroupDO> page); | |
| 34 | + | |
| 35 | + @Named("convertList2") | |
| 36 | + List<BpmUserGroupRespVO> convertList2(List<BpmUserGroupDO> list); | |
| 37 | + | |
| 38 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/message/BpmMessageConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.message; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO; | |
| 4 | +import org.mapstruct.Mapper; | |
| 5 | +import org.mapstruct.factory.Mappers; | |
| 6 | + | |
| 7 | +import java.util.Map; | |
| 8 | + | |
| 9 | +@Mapper | |
| 10 | +public interface BpmMessageConvert { | |
| 11 | + | |
| 12 | + BpmMessageConvert INSTANCE = Mappers.getMapper(BpmMessageConvert.class); | |
| 13 | + | |
| 14 | + SmsSendSingleToUserReqDTO convert(Long userId, String templateCode, Map<String, Object> templateParams); | |
| 15 | + | |
| 16 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOALeaveConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.oa; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveCreateReqVO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveRespVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO; | |
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 7 | +import org.mapstruct.Mapper; | |
| 8 | +import org.mapstruct.factory.Mappers; | |
| 9 | + | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * 请假申请 Convert | |
| 14 | + * | |
| 15 | + * @author 芋艿 | |
| 16 | + */ | |
| 17 | +@Mapper | |
| 18 | +public interface BpmOALeaveConvert { | |
| 19 | + | |
| 20 | + BpmOALeaveConvert INSTANCE = Mappers.getMapper(BpmOALeaveConvert.class); | |
| 21 | + | |
| 22 | + BpmOALeaveDO convert(BpmOALeaveCreateReqVO bean); | |
| 23 | + | |
| 24 | + BpmOALeaveRespVO convert(BpmOALeaveDO bean); | |
| 25 | + | |
| 26 | + List<BpmOALeaveRespVO> convertList(List<BpmOALeaveDO> list); | |
| 27 | + | |
| 28 | + PageResult<BpmOALeaveRespVO> convertPage(PageResult<BpmOALeaveDO> page); | |
| 29 | + | |
| 30 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; | |
| 4 | +import org.flowable.engine.history.HistoricActivityInstance; | |
| 5 | +import org.mapstruct.Mapper; | |
| 6 | +import org.mapstruct.Mapping; | |
| 7 | +import org.mapstruct.Mappings; | |
| 8 | +import org.mapstruct.factory.Mappers; | |
| 9 | + | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * BPM 活动 Convert | |
| 14 | + * | |
| 15 | + * @author 芋道源码 | |
| 16 | + */ | |
| 17 | +@Mapper | |
| 18 | +public interface BpmActivityConvert { | |
| 19 | + | |
| 20 | + BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class); | |
| 21 | + | |
| 22 | + List<BpmActivityRespVO> convertList(List<HistoricActivityInstance> list); | |
| 23 | + | |
| 24 | + @Mappings({ | |
| 25 | + @Mapping(source = "activityId", target = "key"), | |
| 26 | + @Mapping(source = "activityType", target = "type") | |
| 27 | + }) | |
| 28 | + BpmActivityRespVO convert(HistoricActivityInstance bean); | |
| 29 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent; | |
| 10 | +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; | |
| 11 | +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO; | |
| 12 | +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | |
| 13 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 14 | +import org.flowable.engine.history.HistoricProcessInstance; | |
| 15 | +import org.flowable.engine.repository.ProcessDefinition; | |
| 16 | +import org.flowable.engine.runtime.ProcessInstance; | |
| 17 | +import org.flowable.task.api.Task; | |
| 18 | +import org.mapstruct.Mapper; | |
| 19 | +import org.mapstruct.Mapping; | |
| 20 | +import org.mapstruct.MappingTarget; | |
| 21 | +import org.mapstruct.Mappings; | |
| 22 | +import org.mapstruct.factory.Mappers; | |
| 23 | + | |
| 24 | +import java.util.List; | |
| 25 | +import java.util.Map; | |
| 26 | +import java.util.Optional; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * 流程实例 Convert | |
| 30 | + * | |
| 31 | + * @author 芋道源码 | |
| 32 | + */ | |
| 33 | +@Mapper | |
| 34 | +public interface BpmProcessInstanceConvert { | |
| 35 | + | |
| 36 | + BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class); | |
| 37 | + | |
| 38 | + default PageResult<BpmProcessInstancePageItemRespVO> convertPage(PageResult<BpmProcessInstanceExtDO> page, | |
| 39 | + Map<String, List<Task>> taskMap) { | |
| 40 | + List<BpmProcessInstancePageItemRespVO> list = convertList(page.getList()); | |
| 41 | + list.forEach(respVO -> respVO.setTasks(convertList2(taskMap.get(respVO.getId())))); | |
| 42 | + return new PageResult<>(list, page.getTotal()); | |
| 43 | + } | |
| 44 | + | |
| 45 | + List<BpmProcessInstancePageItemRespVO> convertList(List<BpmProcessInstanceExtDO> list); | |
| 46 | + | |
| 47 | + @Mapping(source = "processInstanceId", target = "id") | |
| 48 | + BpmProcessInstancePageItemRespVO convert(BpmProcessInstanceExtDO bean); | |
| 49 | + | |
| 50 | + List<BpmProcessInstancePageItemRespVO.Task> convertList2(List<Task> tasks); | |
| 51 | + | |
| 52 | + default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance, BpmProcessInstanceExtDO processInstanceExt, | |
| 53 | + ProcessDefinition processDefinition, BpmProcessDefinitionExtDO processDefinitionExt, | |
| 54 | + String bpmnXml, AdminUserRespDTO startUser, DeptRespDTO dept) { | |
| 55 | + BpmProcessInstanceRespVO respVO = convert2(processInstance); | |
| 56 | + copyTo(processInstanceExt, respVO); | |
| 57 | + // definition | |
| 58 | + respVO.setProcessDefinition(convert2(processDefinition)); | |
| 59 | + copyTo(processDefinitionExt, respVO.getProcessDefinition()); | |
| 60 | + respVO.getProcessDefinition().setBpmnXml(bpmnXml); | |
| 61 | + // user | |
| 62 | + if (startUser != null) { | |
| 63 | + respVO.setStartUser(convert2(startUser)); | |
| 64 | + if (dept != null) { | |
| 65 | + respVO.getStartUser().setDeptName(dept.getName()); | |
| 66 | + } | |
| 67 | + } | |
| 68 | + return respVO; | |
| 69 | + } | |
| 70 | + | |
| 71 | + BpmProcessInstanceRespVO convert2(HistoricProcessInstance bean); | |
| 72 | + | |
| 73 | + @Mapping(source = "from.id", target = "to.id", ignore = true) | |
| 74 | + void copyTo(BpmProcessInstanceExtDO from, @MappingTarget BpmProcessInstanceRespVO to); | |
| 75 | + | |
| 76 | + BpmProcessInstanceRespVO.ProcessDefinition convert2(ProcessDefinition bean); | |
| 77 | + | |
| 78 | + @Mapping(source = "from.id", target = "to.id", ignore = true) | |
| 79 | + void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to); | |
| 80 | + | |
| 81 | + BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean); | |
| 82 | + | |
| 83 | + default BpmProcessInstanceResultEvent convert(Object source, HistoricProcessInstance instance, Integer result) { | |
| 84 | + BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source); | |
| 85 | + event.setId(instance.getId()); | |
| 86 | + event.setProcessDefinitionKey(instance.getProcessDefinitionKey()); | |
| 87 | + event.setBusinessKey(instance.getBusinessKey()); | |
| 88 | + event.setResult(result); | |
| 89 | + return event; | |
| 90 | + } | |
| 91 | + | |
| 92 | + default BpmProcessInstanceResultEvent convert(Object source, ProcessInstance instance, Integer result) { | |
| 93 | + BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source); | |
| 94 | + event.setId(instance.getId()); | |
| 95 | + event.setProcessDefinitionKey(instance.getProcessDefinitionKey()); | |
| 96 | + event.setBusinessKey(instance.getBusinessKey()); | |
| 97 | + event.setResult(result); | |
| 98 | + return event; | |
| 99 | + } | |
| 100 | + | |
| 101 | + default BpmMessageSendWhenProcessInstanceApproveReqDTO convert2ApprovedReq(ProcessInstance instance){ | |
| 102 | + return new BpmMessageSendWhenProcessInstanceApproveReqDTO() | |
| 103 | + .setStartUserId(NumberUtils.parseLong(instance.getStartUserId())) | |
| 104 | + .setProcessInstanceId(instance.getId()) | |
| 105 | + .setProcessInstanceName(instance.getName()); | |
| 106 | + } | |
| 107 | + | |
| 108 | + default BpmMessageSendWhenProcessInstanceRejectReqDTO convert2RejectReq(ProcessInstance instance, String comment) { | |
| 109 | + return new BpmMessageSendWhenProcessInstanceRejectReqDTO() | |
| 110 | + .setProcessInstanceName(instance.getName()) | |
| 111 | + .setProcessInstanceId(instance.getId()) | |
| 112 | + .setComment(comment) | |
| 113 | + .setStartUserId(NumberUtils.parseLong(instance.getStartUserId())); | |
| 114 | + } | |
| 115 | + | |
| 116 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskDonePageItemRespVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; | |
| 10 | +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | |
| 11 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 12 | + | |
| 13 | +import org.flowable.common.engine.impl.db.SuspensionState; | |
| 14 | +import org.flowable.engine.history.HistoricProcessInstance; | |
| 15 | +import org.flowable.engine.runtime.ProcessInstance; | |
| 16 | +import org.flowable.task.api.Task; | |
| 17 | +import org.flowable.task.api.history.HistoricTaskInstance; | |
| 18 | +import org.mapstruct.*; | |
| 19 | +import org.mapstruct.factory.Mappers; | |
| 20 | + | |
| 21 | +import java.util.List; | |
| 22 | +import java.util.Map; | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * Bpm 任务 Convert | |
| 26 | + * | |
| 27 | + * @author 芋道源码 | |
| 28 | + */ | |
| 29 | +@Mapper | |
| 30 | +public interface BpmTaskConvert { | |
| 31 | + | |
| 32 | + BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class); | |
| 33 | + | |
| 34 | + default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap, | |
| 35 | + Map<Long, AdminUserRespDTO> userMap) { | |
| 36 | + return CollectionUtils.convertList(tasks, task -> { | |
| 37 | + BpmTaskTodoPageItemRespVO respVO = convert1(task); | |
| 38 | + ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId()); | |
| 39 | + if (processInstance != null) { | |
| 40 | + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); | |
| 41 | + respVO.setProcessInstance(convert(processInstance, startUser)); | |
| 42 | + } | |
| 43 | + return respVO; | |
| 44 | + }); | |
| 45 | + } | |
| 46 | + | |
| 47 | + @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState") | |
| 48 | + BpmTaskTodoPageItemRespVO convert1(Task bean); | |
| 49 | + | |
| 50 | + @Named("convertSuspendedToSuspensionState") | |
| 51 | + default Integer convertSuspendedToSuspensionState(boolean suspended) { | |
| 52 | + return suspended ? SuspensionState.SUSPENDED.getStateCode() : | |
| 53 | + SuspensionState.ACTIVE.getStateCode(); | |
| 54 | + } | |
| 55 | + | |
| 56 | + default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap, | |
| 57 | + Map<String, HistoricProcessInstance> historicProcessInstanceMap, | |
| 58 | + Map<Long, AdminUserRespDTO> userMap) { | |
| 59 | + return CollectionUtils.convertList(tasks, task -> { | |
| 60 | + BpmTaskDonePageItemRespVO respVO = convert2(task); | |
| 61 | + BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId()); | |
| 62 | + copyTo(taskExtDO, respVO); | |
| 63 | + HistoricProcessInstance processInstance = historicProcessInstanceMap.get(task.getProcessInstanceId()); | |
| 64 | + if (processInstance != null) { | |
| 65 | + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); | |
| 66 | + respVO.setProcessInstance(convert(processInstance, startUser)); | |
| 67 | + } | |
| 68 | + return respVO; | |
| 69 | + }); | |
| 70 | + } | |
| 71 | + | |
| 72 | + BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean); | |
| 73 | + | |
| 74 | + @Mappings({ | |
| 75 | + @Mapping(source = "processInstance.id", target = "id"), | |
| 76 | + @Mapping(source = "processInstance.name", target = "name"), | |
| 77 | + @Mapping(source = "processInstance.startUserId", target = "startUserId"), | |
| 78 | + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"), | |
| 79 | + @Mapping(source = "startUser.nickname", target = "startUserNickname") | |
| 80 | + }) | |
| 81 | + BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser); | |
| 82 | + | |
| 83 | + default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap, | |
| 84 | + HistoricProcessInstance processInstance, Map<Long, AdminUserRespDTO> userMap, | |
| 85 | + Map<Long, DeptRespDTO> deptMap) { | |
| 86 | + return CollectionUtils.convertList(tasks, task -> { | |
| 87 | + BpmTaskRespVO respVO = convert3(task); | |
| 88 | + BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId()); | |
| 89 | + copyTo(taskExtDO, respVO); | |
| 90 | + if (processInstance != null) { | |
| 91 | + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); | |
| 92 | + respVO.setProcessInstance(convert(processInstance, startUser)); | |
| 93 | + } | |
| 94 | + AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee())); | |
| 95 | + if (assignUser != null) { | |
| 96 | + respVO.setAssigneeUser(convert3(assignUser)); | |
| 97 | + DeptRespDTO dept = deptMap.get(assignUser.getDeptId()); | |
| 98 | + if (dept != null) { | |
| 99 | + respVO.getAssigneeUser().setDeptName(dept.getName()); | |
| 100 | + } | |
| 101 | + } | |
| 102 | + return respVO; | |
| 103 | + }); | |
| 104 | + } | |
| 105 | + | |
| 106 | + @Mapping(source = "taskDefinitionKey", target = "definitionKey") | |
| 107 | + BpmTaskRespVO convert3(HistoricTaskInstance bean); | |
| 108 | + | |
| 109 | + BpmTaskRespVO.User convert3(AdminUserRespDTO bean); | |
| 110 | + | |
| 111 | + @Mapping(target = "id", ignore = true) | |
| 112 | + void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to); | |
| 113 | + | |
| 114 | + @Mappings({ | |
| 115 | + @Mapping(source = "processInstance.id", target = "id"), | |
| 116 | + @Mapping(source = "processInstance.name", target = "name"), | |
| 117 | + @Mapping(source = "processInstance.startUserId", target = "startUserId"), | |
| 118 | + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"), | |
| 119 | + @Mapping(source = "startUser.nickname", target = "startUserNickname") | |
| 120 | + }) | |
| 121 | + BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser); | |
| 122 | + | |
| 123 | + default BpmTaskExtDO convert2TaskExt(Task task){ | |
| 124 | + BpmTaskExtDO taskExtDO = new BpmTaskExtDO() | |
| 125 | + .setTaskId(task.getId()) | |
| 126 | + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())) | |
| 127 | + .setName(task.getName()) | |
| 128 | + .setProcessDefinitionId(task.getProcessDefinitionId()) | |
| 129 | + .setProcessInstanceId(task.getProcessInstanceId()); | |
| 130 | + taskExtDO.setCreateTime(task.getCreateTime()); | |
| 131 | + return taskExtDO; | |
| 132 | + } | |
| 133 | + | |
| 134 | + default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser, Task task) { | |
| 135 | + BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO(); | |
| 136 | + reqDTO.setProcessInstanceId(processInstance.getProcessInstanceId()) | |
| 137 | + .setProcessInstanceName(processInstance.getName()) | |
| 138 | + .setStartUserId(startUser.getId()) | |
| 139 | + .setStartUserNickname(startUser.getNickname()) | |
| 140 | + .setTaskId(task.getId()) | |
| 141 | + .setTaskName(task.getName()) | |
| 142 | + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())); | |
| 143 | + return reqDTO; | |
| 144 | + } | |
| 145 | +} | |
| 146 | + | |
| 147 | + | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.convert.task; | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md
0 → 100644
| 1 | +<http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao> | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmFormDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 4 | +import com.baomidou.mybatisplus.annotation.TableField; | |
| 5 | +import com.baomidou.mybatisplus.annotation.TableId; | |
| 6 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 7 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 8 | +import lombok.*; | |
| 9 | + | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * 工作流的表单定义 | |
| 14 | + * 用于工作流的申请表单,需要动态配置的场景 | |
| 15 | + * | |
| 16 | + * @author 芋道源码 | |
| 17 | + */ | |
| 18 | +@TableName(value = "bpm_form", autoResultMap = true) | |
| 19 | +@Data | |
| 20 | +@EqualsAndHashCode(callSuper = true) | |
| 21 | +@ToString(callSuper = true) | |
| 22 | +@Builder | |
| 23 | +@NoArgsConstructor | |
| 24 | +@AllArgsConstructor | |
| 25 | +public class BpmFormDO extends BaseDO { | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * 编号 | |
| 29 | + */ | |
| 30 | + @TableId | |
| 31 | + private Long id; | |
| 32 | + /** | |
| 33 | + * 表单名 | |
| 34 | + */ | |
| 35 | + private String name; | |
| 36 | + /** | |
| 37 | + * 状态 | |
| 38 | + */ | |
| 39 | + private Integer status; | |
| 40 | + /** | |
| 41 | + * 表单的配置 | |
| 42 | + */ | |
| 43 | + private String conf; | |
| 44 | + /** | |
| 45 | + * 表单项的数组 | |
| 46 | + * | |
| 47 | + * 目前直接将 https://github.com/JakHuang/form-generator 生成的 JSON 串,直接保存 | |
| 48 | + * 定义:https://github.com/JakHuang/form-generator/issues/46 | |
| 49 | + */ | |
| 50 | + @TableField(typeHandler = JacksonTypeHandler.class) | |
| 51 | + private List<String> fields; | |
| 52 | + /** | |
| 53 | + * 备注 | |
| 54 | + */ | |
| 55 | + private String remark; | |
| 56 | + | |
| 57 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; | |
| 5 | +import com.baomidou.mybatisplus.annotation.TableField; | |
| 6 | +import com.baomidou.mybatisplus.annotation.TableId; | |
| 7 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 8 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 9 | +import lombok.*; | |
| 10 | + | |
| 11 | +import java.util.List; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * Bpm 流程定义的拓展表 | |
| 15 | + * 主要解决 Activiti {@link ProcessDefinition} 不支持拓展字段,所以新建拓展表 | |
| 16 | + * | |
| 17 | + * @author 芋道源码 | |
| 18 | + */ | |
| 19 | +@TableName(value = "bpm_process_definition_ext", autoResultMap = true) | |
| 20 | +@Data | |
| 21 | +@EqualsAndHashCode(callSuper = true) | |
| 22 | +@ToString(callSuper = true) | |
| 23 | +@Builder | |
| 24 | +@NoArgsConstructor | |
| 25 | +@AllArgsConstructor | |
| 26 | +public class BpmProcessDefinitionExtDO extends BaseDO { | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 编号 | |
| 30 | + */ | |
| 31 | + @TableId | |
| 32 | + private Long id; | |
| 33 | + /** | |
| 34 | + * 流程定义的编号 | |
| 35 | + * | |
| 36 | + * 关联 ProcessDefinition 的 id 属性 | |
| 37 | + */ | |
| 38 | + private String processDefinitionId; | |
| 39 | + /** | |
| 40 | + * 流程模型的编号 | |
| 41 | + * | |
| 42 | + * 关联 Model 的 id 属性 | |
| 43 | + */ | |
| 44 | + private String modelId; | |
| 45 | + /** | |
| 46 | + * 描述 | |
| 47 | + */ | |
| 48 | + private String description; | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * 表单类型 | |
| 52 | + * | |
| 53 | + * 关联 {@link BpmModelFormTypeEnum} | |
| 54 | + */ | |
| 55 | + private Integer formType; | |
| 56 | + /** | |
| 57 | + * 动态表单编号 | |
| 58 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 59 | + * | |
| 60 | + * 关联 {@link BpmFormDO#getId()} | |
| 61 | + */ | |
| 62 | + private Long formId; | |
| 63 | + /** | |
| 64 | + * 表单的配置 | |
| 65 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 66 | + * | |
| 67 | + * 冗余 {@link BpmFormDO#getConf()} | |
| 68 | + */ | |
| 69 | + private String formConf; | |
| 70 | + /** | |
| 71 | + * 表单项的数组 | |
| 72 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 73 | + * | |
| 74 | + * 冗余 {@link BpmFormDO#getFields()} ()} | |
| 75 | + */ | |
| 76 | + @TableField(typeHandler = JacksonTypeHandler.class) | |
| 77 | + private List<String> formFields; | |
| 78 | + /** | |
| 79 | + * 自定义表单的提交路径,使用 Vue 的路由地址 | |
| 80 | + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 | |
| 81 | + */ | |
| 82 | + private String formCustomCreatePath; | |
| 83 | + /** | |
| 84 | + * 自定义表单的查看路径,使用 Vue 的路由地址 | |
| 85 | + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 | |
| 86 | + */ | |
| 87 | + private String formCustomViewPath; | |
| 88 | + | |
| 89 | + | |
| 90 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 6 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; | |
| 7 | +import com.baomidou.mybatisplus.annotation.TableField; | |
| 8 | +import com.baomidou.mybatisplus.annotation.TableId; | |
| 9 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 10 | +import lombok.*; | |
| 11 | + | |
| 12 | +import java.util.Set; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * Bpm 任务分配的规则表,用于自定义配置每个任务的负责人、候选人的分配规则。 | |
| 16 | + * 也就是说,废弃 BPMN 原本的 UserTask 设置的 assignee、candidateUsers 等配置,而是通过使用该规则进行计算对应的负责人。 | |
| 17 | + * | |
| 18 | + * 1. 默认情况下,{@link #processDefinitionId} 为 {@link #PROCESS_DEFINITION_ID_NULL} 值,表示贵改则与流程模型关联 | |
| 19 | + * 2. 在流程模型部署后,会将他的所有规则记录,复制出一份新部署出来的流程定义,通过设置 {@link #processDefinitionId} 为新的流程定义的编号进行关联 | |
| 20 | + * | |
| 21 | + * @author 芋道源码 | |
| 22 | + */ | |
| 23 | +@TableName(value = "bpm_task_assign_rule", autoResultMap = true) | |
| 24 | +@Data | |
| 25 | +@EqualsAndHashCode(callSuper = true) | |
| 26 | +@ToString(callSuper = true) | |
| 27 | +@Builder | |
| 28 | +@NoArgsConstructor | |
| 29 | +@AllArgsConstructor | |
| 30 | +public class BpmTaskAssignRuleDO extends BaseDO { | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * {@link #processDefinitionId} 空串,用于标识属于流程模型,而不属于流程定义 | |
| 34 | + */ | |
| 35 | + public static final String PROCESS_DEFINITION_ID_NULL = ""; | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * 编号 | |
| 39 | + */ | |
| 40 | + @TableId | |
| 41 | + private Long id; | |
| 42 | + | |
| 43 | + /** | |
| 44 | + * 流程模型编号 | |
| 45 | + * | |
| 46 | + * 关联 Model 的 id 属性 | |
| 47 | + */ | |
| 48 | + private String modelId; | |
| 49 | + /** | |
| 50 | + * 流程定义编号 | |
| 51 | + * | |
| 52 | + * 关联 ProcessDefinition 的 id 属性 | |
| 53 | + */ | |
| 54 | + private String processDefinitionId; | |
| 55 | + /** | |
| 56 | + * 流程任务的定义 Key | |
| 57 | + * | |
| 58 | + * 关联 Task 的 taskDefinitionKey 属性 | |
| 59 | + */ | |
| 60 | + private String taskDefinitionKey; | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * 规则类型 | |
| 64 | + * | |
| 65 | + * 枚举 {@link BpmTaskAssignRuleTypeEnum} | |
| 66 | + */ | |
| 67 | + @TableField("`type`") | |
| 68 | + private Integer type; | |
| 69 | + /** | |
| 70 | + * 规则值数组,一般关联指定表的编号 | |
| 71 | + * 根据 type 不同,对应的值是不同的: | |
| 72 | + * | |
| 73 | + * 1. {@link BpmTaskAssignRuleTypeEnum#ROLE} 时:角色编号 | |
| 74 | + * 2. {@link BpmTaskAssignRuleTypeEnum#DEPT_MEMBER} 时:部门编号 | |
| 75 | + * 3. {@link BpmTaskAssignRuleTypeEnum#DEPT_LEADER} 时:部门编号 | |
| 76 | + * 4. {@link BpmTaskAssignRuleTypeEnum#USER} 时:用户编号 | |
| 77 | + * 5. {@link BpmTaskAssignRuleTypeEnum#USER_GROUP} 时:用户组编号 | |
| 78 | + * 6. {@link BpmTaskAssignRuleTypeEnum#SCRIPT} 时:脚本编号,目前通过 {@link BpmTaskRuleScriptEnum#getId()} 标识 | |
| 79 | + */ | |
| 80 | + @TableField(typeHandler = JsonLongSetTypeHandler.class) | |
| 81 | + private Set<Long> options; | |
| 82 | + | |
| 83 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskMessageRuleDO.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; | |
| 6 | +import com.baomidou.mybatisplus.annotation.TableField; | |
| 7 | +import com.baomidou.mybatisplus.annotation.TableId; | |
| 8 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 9 | +import lombok.*; | |
| 10 | + | |
| 11 | +import java.util.Set; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * Bpm 用户组 | |
| 15 | + * | |
| 16 | + * @author 芋道源码 | |
| 17 | + */ | |
| 18 | +@TableName(value = "bpm_user_group", autoResultMap = true) | |
| 19 | +@Data | |
| 20 | +@EqualsAndHashCode(callSuper = true) | |
| 21 | +@ToString(callSuper = true) | |
| 22 | +@Builder | |
| 23 | +@NoArgsConstructor | |
| 24 | +@AllArgsConstructor | |
| 25 | +public class BpmUserGroupDO extends BaseDO { | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * 编号,自增 | |
| 29 | + */ | |
| 30 | + @TableId | |
| 31 | + private Long id; | |
| 32 | + /** | |
| 33 | + * 组名 | |
| 34 | + */ | |
| 35 | + private String name; | |
| 36 | + /** | |
| 37 | + * 描述 | |
| 38 | + */ | |
| 39 | + private String description; | |
| 40 | + /** | |
| 41 | + * 状态 | |
| 42 | + * | |
| 43 | + * 枚举 {@link CommonStatusEnum} | |
| 44 | + */ | |
| 45 | + private Integer status; | |
| 46 | + /** | |
| 47 | + * 成员用户编号数组 | |
| 48 | + */ | |
| 49 | + @TableField(typeHandler = JsonLongSetTypeHandler.class) | |
| 50 | + private Set<Long> memberUserIds; | |
| 51 | + | |
| 52 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.dataobject.oa; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 4 | +import lombok.*; | |
| 5 | +import java.util.*; | |
| 6 | +import com.baomidou.mybatisplus.annotation.*; | |
| 7 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * OA 请假申请 DO | |
| 11 | + * | |
| 12 | + * {@link #day} 请假天数,目前先简单做。一般是分成请假上午和下午,可以是 1 整天,可以是 0.5 半天 | |
| 13 | + * | |
| 14 | + * @author jason | |
| 15 | + * @author 芋道源码 | |
| 16 | + */ | |
| 17 | +@TableName("bpm_oa_leave") | |
| 18 | +@Data | |
| 19 | +@EqualsAndHashCode(callSuper = true) | |
| 20 | +@ToString(callSuper = true) | |
| 21 | +@Builder | |
| 22 | +@NoArgsConstructor | |
| 23 | +@AllArgsConstructor | |
| 24 | +public class BpmOALeaveDO extends BaseDO { | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * 请假表单主键 | |
| 28 | + */ | |
| 29 | + @TableId | |
| 30 | + private Long id; | |
| 31 | + /** | |
| 32 | + * 申请人的用户编号 | |
| 33 | + * | |
| 34 | + * 关联 AdminUserDO 的 id 属性 | |
| 35 | + */ | |
| 36 | + private Long userId; | |
| 37 | + /** | |
| 38 | + * 请假类型 | |
| 39 | + */ | |
| 40 | + @TableField("`type`") | |
| 41 | + private String type; | |
| 42 | + /** | |
| 43 | + * 原因 | |
| 44 | + */ | |
| 45 | + private String reason; | |
| 46 | + /** | |
| 47 | + * 开始时间 | |
| 48 | + */ | |
| 49 | + private Date startTime; | |
| 50 | + /** | |
| 51 | + * 结束时间 | |
| 52 | + */ | |
| 53 | + private Date endTime; | |
| 54 | + /** | |
| 55 | + * 请假天数 | |
| 56 | + */ | |
| 57 | + private Long day; | |
| 58 | + /** | |
| 59 | + * 请假的结果 | |
| 60 | + * | |
| 61 | + * 枚举 {@link BpmProcessInstanceResultEnum} | |
| 62 | + * 考虑到简单,所以直接复用了 BpmProcessInstanceResultEnum 枚举,也可以自己定义一个枚举哈 | |
| 63 | + */ | |
| 64 | + private Integer result; | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * 对应的流程编号 | |
| 68 | + * | |
| 69 | + * 关联 ProcessInstance 的 id 属性 | |
| 70 | + */ | |
| 71 | + private String processInstanceId; | |
| 72 | + | |
| 73 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.dataobject.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; | |
| 6 | +import com.baomidou.mybatisplus.annotation.TableField; | |
| 7 | +import com.baomidou.mybatisplus.annotation.TableId; | |
| 8 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 9 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 10 | +import lombok.Data; | |
| 11 | +import lombok.EqualsAndHashCode; | |
| 12 | +import lombok.ToString; | |
| 13 | + | |
| 14 | +import java.util.Date; | |
| 15 | +import java.util.Map; | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Bpm 流程实例的拓展表 | |
| 19 | + * 主要解决 Activiti ProcessInstance 和 HistoricProcessInstance 不支持拓展字段,所以新建拓展表 | |
| 20 | + * | |
| 21 | + * @author 芋道源码 | |
| 22 | + */ | |
| 23 | +@TableName(value = "bpm_process_instance_ext", autoResultMap = true) | |
| 24 | +@Data | |
| 25 | +@EqualsAndHashCode(callSuper = true) | |
| 26 | +@ToString(callSuper = true) | |
| 27 | +public class BpmProcessInstanceExtDO extends BaseDO { | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * 编号,自增 | |
| 31 | + */ | |
| 32 | + @TableId | |
| 33 | + private Long id; | |
| 34 | + /** | |
| 35 | + * 发起流程的用户编号 | |
| 36 | + * | |
| 37 | + * 冗余 HistoricProcessInstance 的 startUserId 属性 | |
| 38 | + */ | |
| 39 | + private Long startUserId; | |
| 40 | + /** | |
| 41 | + * 流程实例的名字 | |
| 42 | + * | |
| 43 | + * 冗余 ProcessInstance 的 name 属性,用于筛选 | |
| 44 | + */ | |
| 45 | + private String name; | |
| 46 | + /** | |
| 47 | + * 流程实例的编号 | |
| 48 | + * | |
| 49 | + * 关联 ProcessInstance 的 id 属性 | |
| 50 | + */ | |
| 51 | + private String processInstanceId; | |
| 52 | + /** | |
| 53 | + * 流程定义的编号 | |
| 54 | + * | |
| 55 | + * 关联 ProcessDefinition 的 id 属性 | |
| 56 | + */ | |
| 57 | + private String processDefinitionId; | |
| 58 | + /** | |
| 59 | + * 流程分类 | |
| 60 | + * | |
| 61 | + * 冗余 ProcessDefinition 的 category 属性 | |
| 62 | + * 数据字典 bpm_model_category | |
| 63 | + */ | |
| 64 | + private String category; | |
| 65 | + /** | |
| 66 | + * 流程实例的状态 | |
| 67 | + * | |
| 68 | + * 枚举 {@link BpmProcessInstanceStatusEnum} | |
| 69 | + */ | |
| 70 | + private Integer status; | |
| 71 | + /** | |
| 72 | + * 流程实例的结果 | |
| 73 | + * | |
| 74 | + * 枚举 {@link BpmProcessInstanceResultEnum} | |
| 75 | + */ | |
| 76 | + private Integer result; | |
| 77 | + /** | |
| 78 | + * 结束时间 | |
| 79 | + * | |
| 80 | + * 冗余 HistoricProcessInstance 的 endTime 属性 | |
| 81 | + */ | |
| 82 | + private Date endTime; | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * 提交的表单值 | |
| 86 | + */ | |
| 87 | + @TableField(typeHandler = JacksonTypeHandler.class) | |
| 88 | + private Map<String, Object> formVariables; | |
| 89 | + | |
| 90 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.dataobject.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 5 | +import com.baomidou.mybatisplus.annotation.TableId; | |
| 6 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 7 | +import lombok.Data; | |
| 8 | +import lombok.EqualsAndHashCode; | |
| 9 | +import lombok.ToString; | |
| 10 | + | |
| 11 | +import java.util.Date; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * Bpm 流程任务的拓展表 | |
| 15 | + * 主要解决 Activiti Task 和 HistoricTaskInstance 不支持拓展字段,所以新建拓展表 | |
| 16 | + * | |
| 17 | + * @author 芋道源码 | |
| 18 | + */ | |
| 19 | +@TableName(value = "bpm_task_ext", autoResultMap = true) | |
| 20 | +@Data | |
| 21 | +@EqualsAndHashCode(callSuper = true) | |
| 22 | +@ToString(callSuper = true) | |
| 23 | +public class BpmTaskExtDO extends BaseDO { | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * 编号,自增 | |
| 27 | + */ | |
| 28 | + @TableId | |
| 29 | + private Long id; | |
| 30 | + /** | |
| 31 | + * 任务的审批人 | |
| 32 | + * | |
| 33 | + * 冗余 Task 的 assignee 属性 | |
| 34 | + */ | |
| 35 | + private Long assigneeUserId; | |
| 36 | + /** | |
| 37 | + * 任务的名字 | |
| 38 | + * | |
| 39 | + * 冗余 Task 的 name 属性,为了筛选 | |
| 40 | + */ | |
| 41 | + private String name; | |
| 42 | + /** | |
| 43 | + * 任务的编号 | |
| 44 | + * | |
| 45 | + * 关联 Task 的 id 属性 | |
| 46 | + */ | |
| 47 | + private String taskId; | |
| 48 | +// /** | |
| 49 | +// * 任务的标识 | |
| 50 | +// * | |
| 51 | +// * 关联 {@link Task#getTaskDefinitionKey()} | |
| 52 | +// */ | |
| 53 | +// private String definitionKey; | |
| 54 | + /** | |
| 55 | + * 任务的结果 | |
| 56 | + * | |
| 57 | + * 枚举 {@link BpmProcessInstanceResultEnum} | |
| 58 | + */ | |
| 59 | + private Integer result; | |
| 60 | + /** | |
| 61 | + * 审批建议 | |
| 62 | + */ | |
| 63 | + private String comment; | |
| 64 | + /** | |
| 65 | + * 任务的结束时间 | |
| 66 | + * | |
| 67 | + * 冗余 HistoricTaskInstance 的 endTime 属性 | |
| 68 | + */ | |
| 69 | + private Date endTime; | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * 流程实例的编号 | |
| 73 | + * | |
| 74 | + * 关联 ProcessInstance 的 id 属性 | |
| 75 | + */ | |
| 76 | + private String processInstanceId; | |
| 77 | + /** | |
| 78 | + * 流程定义的编号 | |
| 79 | + * | |
| 80 | + * 关联 ProcessDefinition 的 id 属性 | |
| 81 | + */ | |
| 82 | + private String processDefinitionId; | |
| 83 | + | |
| 84 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmFormMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.mysql.definition; | |
| 2 | + | |
| 3 | + | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 7 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 8 | +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; | |
| 9 | +import org.apache.ibatis.annotations.Mapper; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * 动态表单 Mapper | |
| 13 | + * | |
| 14 | + * @author 风里雾里 | |
| 15 | + */ | |
| 16 | +@Mapper | |
| 17 | +public interface BpmFormMapper extends BaseMapperX<BpmFormDO> { | |
| 18 | + | |
| 19 | + default PageResult<BpmFormDO> selectPage(BpmFormPageReqVO reqVO) { | |
| 20 | + return selectPage(reqVO, new QueryWrapperX<BpmFormDO>() | |
| 21 | + .likeIfPresent("name", reqVO.getName()) | |
| 22 | + .orderByDesc("id")); | |
| 23 | + } | |
| 24 | + | |
| 25 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionExtMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.mysql.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 4 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; | |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 6 | +import org.apache.ibatis.annotations.Mapper; | |
| 7 | + | |
| 8 | +import java.util.Collection; | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 11 | +@Mapper | |
| 12 | +public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> { | |
| 13 | + | |
| 14 | + default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) { | |
| 15 | + return selectList("process_definition_id", processDefinitionIds); | |
| 16 | + } | |
| 17 | + | |
| 18 | + default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) { | |
| 19 | + return selectOne("process_definition_id", processDefinitionId); | |
| 20 | + } | |
| 21 | + | |
| 22 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmTaskAssignRuleMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.mysql.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; | |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; | |
| 6 | +import org.apache.ibatis.annotations.Mapper; | |
| 7 | +import org.springframework.lang.Nullable; | |
| 8 | + | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 11 | +@Mapper | |
| 12 | +public interface BpmTaskAssignRuleMapper extends BaseMapperX<BpmTaskAssignRuleDO> { | |
| 13 | + | |
| 14 | + default List<BpmTaskAssignRuleDO> selectListByProcessDefinitionId(String processDefinitionId, | |
| 15 | + @Nullable String taskDefinitionKey) { | |
| 16 | + return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>() | |
| 17 | + .eq("process_definition_id", processDefinitionId) | |
| 18 | + .eqIfPresent("task_definition_key", taskDefinitionKey)); | |
| 19 | + } | |
| 20 | + | |
| 21 | + default List<BpmTaskAssignRuleDO> selectListByModelId(String modelId) { | |
| 22 | + return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>() | |
| 23 | + .eq("model_id", modelId) | |
| 24 | + .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)); | |
| 25 | + } | |
| 26 | + | |
| 27 | + default BpmTaskAssignRuleDO selectListByModelIdAndTaskDefinitionKey(String modelId, | |
| 28 | + String taskDefinitionKey) { | |
| 29 | + return selectOne(new QueryWrapperX<BpmTaskAssignRuleDO>() | |
| 30 | + .eq("model_id", modelId) | |
| 31 | + .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL) | |
| 32 | + .eq("task_definition_key", taskDefinitionKey)); | |
| 33 | + } | |
| 34 | + | |
| 35 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmUserGroupMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.mysql.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 7 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 8 | +import org.apache.ibatis.annotations.Mapper; | |
| 9 | + | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * 用户组 Mapper | |
| 14 | + * | |
| 15 | + * @author 芋道源码 | |
| 16 | + */ | |
| 17 | +@Mapper | |
| 18 | +public interface BpmUserGroupMapper extends BaseMapperX<BpmUserGroupDO> { | |
| 19 | + | |
| 20 | + default PageResult<BpmUserGroupDO> selectPage(BpmUserGroupPageReqVO reqVO) { | |
| 21 | + return selectPage(reqVO, new LambdaQueryWrapperX<BpmUserGroupDO>() | |
| 22 | + .likeIfPresent(BpmUserGroupDO::getName, reqVO.getName()) | |
| 23 | + .eqIfPresent(BpmUserGroupDO::getStatus, reqVO.getStatus()) | |
| 24 | + .betweenIfPresent(BpmUserGroupDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) | |
| 25 | + .orderByDesc(BpmUserGroupDO::getId)); | |
| 26 | + } | |
| 27 | + | |
| 28 | + default List<BpmUserGroupDO> selectListByStatus(Integer status) { | |
| 29 | + return selectList(BpmUserGroupDO::getStatus, status); | |
| 30 | + } | |
| 31 | + | |
| 32 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.mysql.oa; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeavePageReqVO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 7 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 8 | +import org.apache.ibatis.annotations.Mapper; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * 请假申请 Mapper | |
| 12 | + * | |
| 13 | + * @author jason | |
| 14 | + * @author 芋道源码 | |
| 15 | + */ | |
| 16 | +@Mapper | |
| 17 | +public interface BpmOALeaveMapper extends BaseMapperX<BpmOALeaveDO> { | |
| 18 | + | |
| 19 | + default PageResult<BpmOALeaveDO> selectPage(Long userId, BpmOALeavePageReqVO reqVO) { | |
| 20 | + return selectPage(reqVO, new LambdaQueryWrapperX<BpmOALeaveDO>() | |
| 21 | + .eqIfPresent(BpmOALeaveDO::getUserId, userId) | |
| 22 | + .eqIfPresent(BpmOALeaveDO::getResult, reqVO.getResult()) | |
| 23 | + .eqIfPresent(BpmOALeaveDO::getType, reqVO.getType()) | |
| 24 | + .likeIfPresent(BpmOALeaveDO::getReason, reqVO.getReason()) | |
| 25 | + .betweenIfPresent(BpmOALeaveDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) | |
| 26 | + .orderByDesc(BpmOALeaveDO::getId)); | |
| 27 | + } | |
| 28 | + | |
| 29 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.mysql.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 7 | +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; | |
| 8 | +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |
| 9 | +import org.apache.ibatis.annotations.Mapper; | |
| 10 | + | |
| 11 | +@Mapper | |
| 12 | +public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInstanceExtDO> { | |
| 13 | + | |
| 14 | + default PageResult<BpmProcessInstanceExtDO> selectPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) { | |
| 15 | + return selectPage(reqVO, new QueryWrapperX<BpmProcessInstanceExtDO>() | |
| 16 | + .eqIfPresent("start_user_id", userId) | |
| 17 | + .likeIfPresent("name", reqVO.getName()) | |
| 18 | + .eqIfPresent("process_definition_id", reqVO.getProcessDefinitionId()) | |
| 19 | + .eqIfPresent("category", reqVO.getCategory()) | |
| 20 | + .eqIfPresent("status", reqVO.getStatus()) | |
| 21 | + .eqIfPresent("result", reqVO.getResult()) | |
| 22 | + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) | |
| 23 | + .orderByDesc("id")); | |
| 24 | + } | |
| 25 | + | |
| 26 | + default BpmProcessInstanceExtDO selectByProcessInstanceId(String processDefinitionId) { | |
| 27 | + return selectOne("process_instance_id", processDefinitionId); | |
| 28 | + } | |
| 29 | + | |
| 30 | + default void updateByProcessInstanceId(BpmProcessInstanceExtDO updateObj) { | |
| 31 | + update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>() | |
| 32 | + .eq("process_instance_id", updateObj.getProcessInstanceId())); | |
| 33 | + } | |
| 34 | + | |
| 35 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.dal.mysql.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; | |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 5 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |
| 6 | +import org.apache.ibatis.annotations.Mapper; | |
| 7 | + | |
| 8 | +import java.util.Collection; | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 11 | +@Mapper | |
| 12 | +public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> { | |
| 13 | + | |
| 14 | + default void updateByTaskId(BpmTaskExtDO entity) { | |
| 15 | + update(entity, new LambdaQueryWrapper<BpmTaskExtDO>().eq(BpmTaskExtDO::getTaskId, entity.getTaskId())); | |
| 16 | + } | |
| 17 | + | |
| 18 | + default List<BpmTaskExtDO> selectListByTaskIds(Collection<String> taskIds) { | |
| 19 | + return selectList(BpmTaskExtDO::getTaskId, taskIds); | |
| 20 | + } | |
| 21 | + | |
| 22 | + default List<BpmTaskExtDO> selectListByProcessInstanceId(String processInstanceId) { | |
| 23 | + return selectList("process_instance_id", processInstanceId); | |
| 24 | + } | |
| 25 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.enums.definition; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * BPM 模型的表单类型的枚举 | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 10 | + */ | |
| 11 | +@Getter | |
| 12 | +@AllArgsConstructor | |
| 13 | +public enum BpmModelFormTypeEnum { | |
| 14 | + | |
| 15 | + NORMAL(10, "流程表单"), // 对应 BpmFormDO | |
| 16 | + CUSTOM(20, "业务表单") // 业务自己定义的表单,自己进行数据的存储 | |
| 17 | + ; | |
| 18 | + | |
| 19 | + private final Integer type; | |
| 20 | + private final String desc; | |
| 21 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.enums.definition; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * BPM 任务分配规则的类型枚举 | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 10 | + */ | |
| 11 | +@Getter | |
| 12 | +@AllArgsConstructor | |
| 13 | +public enum BpmTaskAssignRuleTypeEnum { | |
| 14 | + | |
| 15 | + ROLE(10, "角色"), | |
| 16 | + | |
| 17 | + DEPT_MEMBER(20, "部门的成员"), // 包括负责人 | |
| 18 | + DEPT_LEADER(21, "部门的负责人"), | |
| 19 | + POST(22, "岗位"), | |
| 20 | + | |
| 21 | + USER(30, "用户"), | |
| 22 | + | |
| 23 | + USER_GROUP(40, "用户组"), | |
| 24 | + | |
| 25 | + SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导 | |
| 26 | + ; | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 类型 | |
| 30 | + */ | |
| 31 | + private final Integer type; | |
| 32 | + /** | |
| 33 | + * 描述 | |
| 34 | + */ | |
| 35 | + private final String desc; | |
| 36 | + | |
| 37 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskRuleScriptEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.enums.definition; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * BPM 任务规则的脚本枚举 | |
| 8 | + * 目前暂时通过 TODO 芋艿:硬编码,未来可以考虑 Groovy 动态脚本的方式 | |
| 9 | + * | |
| 10 | + * @author 芋道源码 | |
| 11 | + */ | |
| 12 | +@Getter | |
| 13 | +@AllArgsConstructor | |
| 14 | +public enum BpmTaskRuleScriptEnum { | |
| 15 | + | |
| 16 | + START_USER(10L, "流程发起人"), | |
| 17 | + | |
| 18 | + LEADER_X1(20L, "流程发起人的一级领导"), | |
| 19 | + LEADER_X2(21L, "流程发起人的二级领导"); | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * 脚本编号 | |
| 23 | + */ | |
| 24 | + private final Long id; | |
| 25 | + /** | |
| 26 | + * 脚本描述 | |
| 27 | + */ | |
| 28 | + private final String desc; | |
| 29 | + | |
| 30 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/enums/message/BpmMessageEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.enums.message; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * Bpm 消息的枚举 | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 10 | + */ | |
| 11 | +@AllArgsConstructor | |
| 12 | +@Getter | |
| 13 | +public enum BpmMessageEnum { | |
| 14 | + | |
| 15 | + PROCESS_INSTANCE_APPROVE("bpm_process_instance_approve"), // 流程任务被审批通过时,发送给申请人 | |
| 16 | + PROCESS_INSTANCE_REJECT("bpm_process_instance_reject"), // 流程任务被审批不通过时,发送给申请人 | |
| 17 | + TASK_ASSIGNED("bpm_task_assigned"); // 任务被分配时,发送给审批人 | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * 短信模板的标识 | |
| 21 | + * | |
| 22 | + * 关联 SmsTemplateDO 的 code 属性 | |
| 23 | + */ | |
| 24 | + private final String smsTemplateCode; | |
| 25 | + | |
| 26 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.enums.task; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 4 | +import lombok.AllArgsConstructor; | |
| 5 | +import lombok.Getter; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * 流程实例的删除原因 | |
| 9 | + * | |
| 10 | + * @author 芋道源码 | |
| 11 | + */ | |
| 12 | +@Getter | |
| 13 | +@AllArgsConstructor | |
| 14 | +public enum BpmProcessInstanceDeleteReasonEnum { | |
| 15 | + | |
| 16 | + REJECT_TASK("不通过任务,原因:{}"), // 修改文案时,需要注意 isRejectReason 方法 | |
| 17 | + CANCEL_TASK("主动取消任务,原因:{}"); | |
| 18 | + | |
| 19 | + private final String reason; | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * 格式化理由 | |
| 23 | + * | |
| 24 | + * @param args 参数 | |
| 25 | + * @return 理由 | |
| 26 | + */ | |
| 27 | + public String format(Object... args) { | |
| 28 | + return StrUtil.format(reason, args); | |
| 29 | + } | |
| 30 | + | |
| 31 | + // ========== 逻辑 ========== | |
| 32 | + | |
| 33 | + public static boolean isRejectReason(String reason) { | |
| 34 | + return StrUtil.startWith(reason, "不通过任务,原因:"); | |
| 35 | + } | |
| 36 | + | |
| 37 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.enums.task; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * 流程实例的结果 | |
| 8 | + * | |
| 9 | + * @author jason | |
| 10 | + */ | |
| 11 | +@Getter | |
| 12 | +@AllArgsConstructor | |
| 13 | +public enum BpmProcessInstanceResultEnum { | |
| 14 | + | |
| 15 | + PROCESS(1, "处理中"), | |
| 16 | + APPROVE(2, "通过"), | |
| 17 | + REJECT(3, "不通过"), | |
| 18 | + CANCEL(4, "已取消"); | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * 结果 | |
| 22 | + */ | |
| 23 | + private final Integer result; | |
| 24 | + /** | |
| 25 | + * 描述 | |
| 26 | + */ | |
| 27 | + private final String desc; | |
| 28 | + | |
| 29 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.enums.task; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * 流程实例的状态 | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 10 | + */ | |
| 11 | +@Getter | |
| 12 | +@AllArgsConstructor | |
| 13 | +public enum BpmProcessInstanceStatusEnum { | |
| 14 | + | |
| 15 | + RUNNING(1, "进行中"), | |
| 16 | + FINISH(2, "已完成"); | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * 状态 | |
| 20 | + */ | |
| 21 | + private final Integer status; | |
| 22 | + /** | |
| 23 | + * 描述 | |
| 24 | + */ | |
| 25 | + private final String desc; | |
| 26 | + | |
| 27 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCommonConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.bpm.config; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; | |
| 4 | +import org.springframework.context.ApplicationEventPublisher; | |
| 5 | +import org.springframework.context.annotation.Bean; | |
| 6 | +import org.springframework.context.annotation.Configuration; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * BPM 通用的 Configuration 配置类,提供给 Activiti 和 Flowable | |
| 10 | + */ | |
| 11 | +@Configuration | |
| 12 | +public class BpmCommonConfiguration { | |
| 13 | + | |
| 14 | + @Bean | |
| 15 | + public BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher(ApplicationEventPublisher publisher) { | |
| 16 | + return new BpmProcessInstanceResultEventPublisher(publisher); | |
| 17 | + } | |
| 18 | + | |
| 19 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEvent.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.bpm.core.event; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; | |
| 4 | +import lombok.Data; | |
| 5 | +import org.springframework.context.ApplicationEvent; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotNull; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * 流程实例的结果发生变化的 Event | |
| 11 | + * 定位:由于额外增加了 {@link BpmProcessInstanceExtDO#getResult()} 结果,所以增加该事件 | |
| 12 | + * | |
| 13 | + * @author 芋道源码 | |
| 14 | + */ | |
| 15 | +@SuppressWarnings("ALL") | |
| 16 | +@Data | |
| 17 | +public class BpmProcessInstanceResultEvent extends ApplicationEvent { | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * 流程实例的编号 | |
| 21 | + */ | |
| 22 | + @NotNull(message = "流程实例的编号不能为空") | |
| 23 | + private String id; | |
| 24 | + /** | |
| 25 | + * 流程实例的 key | |
| 26 | + */ | |
| 27 | + @NotNull(message = "流程实例的 key 不能为空") | |
| 28 | + private String processDefinitionKey; | |
| 29 | + /** | |
| 30 | + * 流程实例的结果 | |
| 31 | + */ | |
| 32 | + @NotNull(message = "流程实例的结果不能为空") | |
| 33 | + private Integer result; | |
| 34 | + /** | |
| 35 | + * 流程实例对应的业务标识 | |
| 36 | + * 例如说,请假 | |
| 37 | + */ | |
| 38 | + private String businessKey; | |
| 39 | + | |
| 40 | + public BpmProcessInstanceResultEvent(Object source) { | |
| 41 | + super(source); | |
| 42 | + } | |
| 43 | + | |
| 44 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventListener.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.bpm.core.event; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 4 | +import org.springframework.context.ApplicationListener; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * {@link BpmProcessInstanceResultEvent} 的监听器 | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 10 | + */ | |
| 11 | +public abstract class BpmProcessInstanceResultEventListener | |
| 12 | + implements ApplicationListener<BpmProcessInstanceResultEvent> { | |
| 13 | + | |
| 14 | + @Override | |
| 15 | + public final void onApplicationEvent(BpmProcessInstanceResultEvent event) { | |
| 16 | + if (!StrUtil.equals(event.getProcessDefinitionKey(), getProcessDefinitionKey())) { | |
| 17 | + return; | |
| 18 | + } | |
| 19 | + onEvent(event); | |
| 20 | + } | |
| 21 | + | |
| 22 | + /** | |
| 23 | + * @return 返回监听的流程定义 Key | |
| 24 | + */ | |
| 25 | + protected abstract String getProcessDefinitionKey(); | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * 处理事件 | |
| 29 | + * | |
| 30 | + * @param event 事件 | |
| 31 | + */ | |
| 32 | + protected abstract void onEvent(BpmProcessInstanceResultEvent event); | |
| 33 | + | |
| 34 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventPublisher.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.bpm.core.event; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import org.springframework.context.ApplicationEventPublisher; | |
| 5 | +import org.springframework.validation.annotation.Validated; | |
| 6 | + | |
| 7 | +import javax.validation.Valid; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * {@link BpmProcessInstanceResultEvent} 的生产者 | |
| 11 | + * | |
| 12 | + * @author 芋道源码 | |
| 13 | + */ | |
| 14 | +@AllArgsConstructor | |
| 15 | +@Validated | |
| 16 | +public class BpmProcessInstanceResultEventPublisher { | |
| 17 | + | |
| 18 | + private final ApplicationEventPublisher publisher; | |
| 19 | + | |
| 20 | + public void sendProcessInstanceResultEvent(@Valid BpmProcessInstanceResultEvent event) { | |
| 21 | + publisher.publishEvent(event); | |
| 22 | + } | |
| 23 | + | |
| 24 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/package-info.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/package-info.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/package-info.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.config; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.ListUtil; | |
| 4 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory; | |
| 5 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; | |
| 8 | +import cn.iocoder.yudao.module.system.api.dept.DeptApi; | |
| 9 | +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; | |
| 10 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 11 | +import org.flowable.common.engine.api.delegate.event.FlowableEventListener; | |
| 12 | +import org.flowable.spring.SpringProcessEngineConfiguration; | |
| 13 | +import org.flowable.spring.boot.EngineConfigurationConfigurer; | |
| 14 | +import org.springframework.beans.factory.ObjectProvider; | |
| 15 | +import org.springframework.context.annotation.Bean; | |
| 16 | +import org.springframework.context.annotation.Configuration; | |
| 17 | + | |
| 18 | +import java.util.List; | |
| 19 | + | |
| 20 | +/** | |
| 21 | + * BPM 模块的 Flowable 配置类 | |
| 22 | + * | |
| 23 | + * @author jason | |
| 24 | + */ | |
| 25 | +@Configuration | |
| 26 | +public class BpmFlowableConfiguration { | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类: | |
| 30 | + * | |
| 31 | + * 1. 设置各种监听器 | |
| 32 | + * 2. 设置自定义的 ActivityBehaviorFactory 实现 | |
| 33 | + */ | |
| 34 | + @Bean | |
| 35 | + public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> bpmProcessEngineConfigurationConfigurer( | |
| 36 | + ObjectProvider<FlowableEventListener> listeners, | |
| 37 | + BpmActivityBehaviorFactory bpmActivityBehaviorFactory) { | |
| 38 | + return configuration -> { | |
| 39 | + // 注册监听器,例如说 BpmActivitiEventListener | |
| 40 | + configuration.setEventListeners(ListUtil.toList(listeners.iterator())); | |
| 41 | + // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义 | |
| 42 | + configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory); | |
| 43 | + }; | |
| 44 | + } | |
| 45 | + | |
| 46 | + @Bean | |
| 47 | + public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService, | |
| 48 | + BpmUserGroupService userGroupService, | |
| 49 | + PermissionApi permissionApi, | |
| 50 | + DeptApi deptApi, | |
| 51 | + AdminUserApi adminUserApi, | |
| 52 | + List<BpmTaskAssignScript> scripts) { | |
| 53 | + BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory(); | |
| 54 | + bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService); | |
| 55 | + bpmActivityBehaviorFactory.setUserGroupService(userGroupService); | |
| 56 | + bpmActivityBehaviorFactory.setAdminUserApi(adminUserApi); | |
| 57 | + bpmActivityBehaviorFactory.setPermissionApi(permissionApi); | |
| 58 | + bpmActivityBehaviorFactory.setDeptApi(deptApi); | |
| 59 | + bpmActivityBehaviorFactory.setScripts(scripts); | |
| 60 | + return bpmActivityBehaviorFactory; | |
| 61 | + } | |
| 62 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; | |
| 4 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; | |
| 5 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; | |
| 6 | +import cn.iocoder.yudao.module.system.api.dept.DeptApi; | |
| 7 | +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; | |
| 8 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 9 | +import lombok.Data; | |
| 10 | +import lombok.EqualsAndHashCode; | |
| 11 | +import lombok.Setter; | |
| 12 | +import lombok.ToString; | |
| 13 | +import org.flowable.bpmn.model.UserTask; | |
| 14 | +import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; | |
| 15 | +import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory; | |
| 16 | + | |
| 17 | +import java.util.List; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * 自定义的 ActivityBehaviorFactory 实现类,目的如下: | |
| 21 | + * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配 | |
| 22 | + * | |
| 23 | + * @author 芋道源码 | |
| 24 | + */ | |
| 25 | +@Data | |
| 26 | +@EqualsAndHashCode(callSuper = true) | |
| 27 | +@ToString(callSuper = true) | |
| 28 | +public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory { | |
| 29 | + | |
| 30 | + @Setter | |
| 31 | + private BpmTaskAssignRuleService bpmTaskRuleService; | |
| 32 | + @Setter | |
| 33 | + private BpmUserGroupService userGroupService; | |
| 34 | + | |
| 35 | + @Setter | |
| 36 | + private PermissionApi permissionApi; | |
| 37 | + @Setter | |
| 38 | + private DeptApi deptApi; | |
| 39 | + @Setter | |
| 40 | + private AdminUserApi adminUserApi; | |
| 41 | + @Setter | |
| 42 | + private List<BpmTaskAssignScript> scripts; | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) { | |
| 46 | + BpmUserTaskActivityBehavior userTaskActivityBehavior = new BpmUserTaskActivityBehavior(userTask); | |
| 47 | + userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService); | |
| 48 | + userTaskActivityBehavior.setPermissionApi(permissionApi); | |
| 49 | + userTaskActivityBehavior.setDeptApi(deptApi); | |
| 50 | + userTaskActivityBehavior.setUserGroupService(userGroupService); | |
| 51 | + userTaskActivityBehavior.setAdminUserApi(adminUserApi); | |
| 52 | + userTaskActivityBehavior.setScripts(scripts); | |
| 53 | + return userTaskActivityBehavior; | |
| 54 | + } | |
| 55 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.util.RandomUtil; | |
| 5 | +import cn.hutool.core.util.StrUtil; | |
| 6 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 7 | +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; | |
| 8 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | |
| 10 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 11 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; | |
| 12 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; | |
| 13 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; | |
| 14 | +import cn.iocoder.yudao.module.system.api.dept.DeptApi; | |
| 15 | +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | |
| 16 | +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; | |
| 17 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 18 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 19 | +import com.google.common.annotations.VisibleForTesting; | |
| 20 | +import lombok.Setter; | |
| 21 | +import lombok.extern.slf4j.Slf4j; | |
| 22 | +import org.flowable.bpmn.model.UserTask; | |
| 23 | +import org.flowable.common.engine.api.FlowableException; | |
| 24 | +import org.flowable.common.engine.impl.el.ExpressionManager; | |
| 25 | +import org.flowable.engine.delegate.DelegateExecution; | |
| 26 | +import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; | |
| 27 | +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; | |
| 28 | +import org.flowable.engine.impl.util.TaskHelper; | |
| 29 | +import org.flowable.task.service.TaskService; | |
| 30 | +import org.flowable.task.service.impl.persistence.entity.TaskEntity; | |
| 31 | + | |
| 32 | +import java.util.*; | |
| 33 | + | |
| 34 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 35 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | |
| 36 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 37 | +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | |
| 38 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS; | |
| 39 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER; | |
| 40 | + | |
| 41 | +/** | |
| 42 | + * 自定义的流程任务的 assignee 负责人的分配 | |
| 43 | + * 第一步,获得对应的分配规则; | |
| 44 | + * 第二步,根据分配规则,计算出分配任务的候选人。如果找不到,则直接报业务异常,不继续执行后续的流程; | |
| 45 | + * 第三步,随机选择一个候选人,则选择作为 assignee 负责人。 | |
| 46 | + * | |
| 47 | + * @author 芋道源码 | |
| 48 | + */ | |
| 49 | +@Slf4j | |
| 50 | +public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { | |
| 51 | + | |
| 52 | + @Setter | |
| 53 | + private BpmTaskAssignRuleService bpmTaskRuleService; | |
| 54 | + @Setter | |
| 55 | + private BpmUserGroupService userGroupService; | |
| 56 | + @Setter | |
| 57 | + private DeptApi deptApi; | |
| 58 | + @Setter | |
| 59 | + private AdminUserApi adminUserApi; | |
| 60 | + @Setter | |
| 61 | + private PermissionApi permissionApi; | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * 任务分配脚本 | |
| 65 | + */ | |
| 66 | + private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap(); | |
| 67 | + | |
| 68 | + public BpmUserTaskActivityBehavior(UserTask userTask) { | |
| 69 | + super(userTask); | |
| 70 | + } | |
| 71 | + | |
| 72 | + public void setScripts(List<BpmTaskAssignScript> scripts) { | |
| 73 | + this.scriptMap = convertMap(scripts, script -> script.getEnum().getId()); | |
| 74 | + } | |
| 75 | + | |
| 76 | + @Override | |
| 77 | + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据 | |
| 78 | + protected void handleAssignments(TaskService taskService, String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) { | |
| 79 | + boolean isMultiInstance = hasMultiInstanceCharacteristics(); | |
| 80 | + if(isMultiInstance){ | |
| 81 | + //多实例 会签/或签,执行多次每个人 待办人都在execution里面获取 | |
| 82 | + Integer assigneeUserId = execution.getVariableLocal("user", Integer.class); | |
| 83 | + TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId)); | |
| 84 | + }else { | |
| 85 | + // 第一步,获得任务的规则 | |
| 86 | + BpmTaskAssignRuleDO rule = getTaskRule(task); | |
| 87 | + // 第二步,获得任务的候选用户们 | |
| 88 | + Set<Long> candidateUserIds = calculateTaskCandidateUsers(task, rule); | |
| 89 | + // 第三步,设置一个作为负责人 | |
| 90 | + Long assigneeUserId = chooseTaskAssignee(candidateUserIds); | |
| 91 | + TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId)); | |
| 92 | + } | |
| 93 | + | |
| 94 | + } | |
| 95 | + | |
| 96 | + private BpmTaskAssignRuleDO getTaskRule(TaskEntity task) { | |
| 97 | + List<BpmTaskAssignRuleDO> taskRules = bpmTaskRuleService.getTaskAssignRuleListByProcessDefinitionId(task.getProcessDefinitionId(), | |
| 98 | + task.getTaskDefinitionKey()); | |
| 99 | + if (CollUtil.isEmpty(taskRules)) { | |
| 100 | + throw new FlowableException(StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则", | |
| 101 | + task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey())); | |
| 102 | + } | |
| 103 | + if (taskRules.size() > 1) { | |
| 104 | + throw new FlowableException(StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})", | |
| 105 | + task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), taskRules.size())); | |
| 106 | + } | |
| 107 | + return taskRules.get(0); | |
| 108 | + } | |
| 109 | + | |
| 110 | + Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) { | |
| 111 | + Set<Long> assigneeUserIds = null; | |
| 112 | + if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) { | |
| 113 | + assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule); | |
| 114 | + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) { | |
| 115 | + assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule); | |
| 116 | + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) { | |
| 117 | + assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule); | |
| 118 | + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) { | |
| 119 | + assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule); | |
| 120 | + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) { | |
| 121 | + assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule); | |
| 122 | + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) { | |
| 123 | + assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule); | |
| 124 | + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) { | |
| 125 | + assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule); | |
| 126 | + } | |
| 127 | + | |
| 128 | + // 移除被禁用的用户 | |
| 129 | + removeDisableUsers(assigneeUserIds); | |
| 130 | + // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人 | |
| 131 | + if (CollUtil.isEmpty(assigneeUserIds)) { | |
| 132 | + log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", | |
| 133 | + task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule)); | |
| 134 | + throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER); | |
| 135 | + } | |
| 136 | + return assigneeUserIds; | |
| 137 | + } | |
| 138 | + | |
| 139 | + private Set<Long> calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskAssignRuleDO rule) { | |
| 140 | + return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions()); | |
| 141 | + } | |
| 142 | + | |
| 143 | + private Set<Long> calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) { | |
| 144 | + List<AdminUserRespDTO> users = adminUserApi.getUsersByDeptIds(rule.getOptions()); | |
| 145 | + return convertSet(users, AdminUserRespDTO::getId); | |
| 146 | + } | |
| 147 | + | |
| 148 | + private Set<Long> calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskAssignRuleDO rule) { | |
| 149 | + List<DeptRespDTO> depts = deptApi.getDepts(rule.getOptions()); | |
| 150 | + return convertSet(depts, DeptRespDTO::getLeaderUserId); | |
| 151 | + } | |
| 152 | + | |
| 153 | + private Set<Long> calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) { | |
| 154 | + List<AdminUserRespDTO> users = adminUserApi.getUsersByPostIds(rule.getOptions()); | |
| 155 | + return convertSet(users, AdminUserRespDTO::getId); | |
| 156 | + } | |
| 157 | + | |
| 158 | + private Set<Long> calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) { | |
| 159 | + return rule.getOptions(); | |
| 160 | + } | |
| 161 | + | |
| 162 | + private Set<Long> calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskAssignRuleDO rule) { | |
| 163 | + List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions()); | |
| 164 | + Set<Long> userIds = new HashSet<>(); | |
| 165 | + userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); | |
| 166 | + return userIds; | |
| 167 | + } | |
| 168 | + | |
| 169 | + private Set<Long> calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskAssignRuleDO rule) { | |
| 170 | + // 获得对应的脚本 | |
| 171 | + List<BpmTaskAssignScript> scripts = new ArrayList<>(rule.getOptions().size()); | |
| 172 | + rule.getOptions().forEach(id -> { | |
| 173 | + BpmTaskAssignScript script = scriptMap.get(id); | |
| 174 | + if (script == null) { | |
| 175 | + throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id); | |
| 176 | + } | |
| 177 | + scripts.add(script); | |
| 178 | + }); | |
| 179 | + // 逐个计算任务 | |
| 180 | + Set<Long> userIds = new HashSet<>(); | |
| 181 | + scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(task))); | |
| 182 | + return userIds; | |
| 183 | + } | |
| 184 | + | |
| 185 | + private Long chooseTaskAssignee(Set<Long> candidateUserIds) { | |
| 186 | + // TODO 芋艿:未来可以优化下,改成轮询的策略 | |
| 187 | + int index = RandomUtil.randomInt(candidateUserIds.size()); | |
| 188 | + return CollUtil.get(candidateUserIds, index); | |
| 189 | + } | |
| 190 | + | |
| 191 | + @VisibleForTesting | |
| 192 | + void removeDisableUsers(Set<Long> assigneeUserIds) { | |
| 193 | + if (CollUtil.isEmpty(assigneeUserIds)) { | |
| 194 | + return; | |
| 195 | + } | |
| 196 | + //TODO 芋艿 这里有数据权限的问题。默认会加上数据权限 dept_id IN (deptId). 导致查询不到数据 | |
| 197 | + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assigneeUserIds); | |
| 198 | + assigneeUserIds.removeIf(id -> { | |
| 199 | + AdminUserRespDTO user = userMap.get(id); | |
| 200 | + return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus()); | |
| 201 | + }); | |
| 202 | + } | |
| 203 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; | |
| 4 | +import org.flowable.task.service.impl.persistence.entity.TaskEntity; | |
| 5 | + | |
| 6 | +import java.util.Set; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * Bpm 任务分配的自定义 Script 脚本 | |
| 10 | + * 使用场景: | |
| 11 | + * 1. 设置审批人为发起人 | |
| 12 | + * 2. 设置审批人为发起人的 Leader | |
| 13 | + * 3. 甚至审批人为发起人的 Leader 的 Leader | |
| 14 | + * | |
| 15 | + * @author 芋道源码 | |
| 16 | + */ | |
| 17 | +public interface BpmTaskAssignScript { | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * 基于流程任务,获得任务的候选用户们 | |
| 21 | + * | |
| 22 | + * @param task 任务 | |
| 23 | + * @return 候选人用户的编号数组 | |
| 24 | + */ | |
| 25 | + Set<Long> calculateTaskCandidateUsers(TaskEntity task); | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * 获得枚举值 | |
| 29 | + * | |
| 30 | + * @return 枚举值 | |
| 31 | + */ | |
| 32 | + BpmTaskRuleScriptEnum getEnum(); | |
| 33 | +} | |
| 34 | + | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | |
| 4 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; | |
| 5 | +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; | |
| 6 | +import cn.iocoder.yudao.module.system.api.dept.DeptApi; | |
| 7 | +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | |
| 8 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 9 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 10 | + | |
| 11 | +import org.flowable.engine.runtime.ProcessInstance; | |
| 12 | +import org.flowable.task.service.impl.persistence.entity.TaskEntity; | |
| 13 | +import org.springframework.context.annotation.Lazy; | |
| 14 | +import org.springframework.util.Assert; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | +import java.util.Set; | |
| 18 | + | |
| 19 | +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | |
| 20 | +import static java.util.Collections.emptySet; | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * 分配给发起人的 Leader 审批的 Script 实现类 | |
| 24 | + * 目前 Leader 的定义是, | |
| 25 | + * | |
| 26 | + * @author 芋道源码 | |
| 27 | + */ | |
| 28 | +public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssignScript { | |
| 29 | + | |
| 30 | + @Resource | |
| 31 | + private AdminUserApi adminUserApi; | |
| 32 | + @Resource | |
| 33 | + private DeptApi deptApi; | |
| 34 | + @Resource | |
| 35 | + @Lazy // 解决循环依赖 | |
| 36 | + private BpmProcessInstanceService bpmProcessInstanceService; | |
| 37 | + | |
| 38 | + protected Set<Long> calculateTaskCandidateUsers(TaskEntity task, int level) { | |
| 39 | + Assert.isTrue(level > 0, "level 必须大于 0"); | |
| 40 | + // 获得发起人 | |
| 41 | + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId()); | |
| 42 | + Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); | |
| 43 | + // 获得对应 leve 的部门 | |
| 44 | + DeptRespDTO dept = null; | |
| 45 | + for (int i = 0; i < level; i++) { | |
| 46 | + // 获得 level 对应的部门 | |
| 47 | + if (dept == null) { | |
| 48 | + dept = getStartUserDept(startUserId); | |
| 49 | + if (dept == null) { // 找不到发起人的部门,所以无法使用该规则 | |
| 50 | + return emptySet(); | |
| 51 | + } | |
| 52 | + } else { | |
| 53 | + DeptRespDTO parentDept = deptApi.getDept(dept.getParentId()); | |
| 54 | + if (parentDept == null) { // 找不到父级部门,所以只好结束寻找。原因是:例如说,级别比较高的人,所在部门层级比较少 | |
| 55 | + break; | |
| 56 | + } | |
| 57 | + dept = parentDept; | |
| 58 | + } | |
| 59 | + } | |
| 60 | + return dept.getLeaderUserId() != null ? asSet(dept.getLeaderUserId()) : emptySet(); | |
| 61 | + } | |
| 62 | + | |
| 63 | + private DeptRespDTO getStartUserDept(Long startUserId) { | |
| 64 | + AdminUserRespDTO startUser = adminUserApi.getUser(startUserId); | |
| 65 | + if (startUser.getDeptId() == null) { // 找不到部门,所以无法使用该规则 | |
| 66 | + return null; | |
| 67 | + } | |
| 68 | + return deptApi.getDept(startUser.getDeptId()); | |
| 69 | + } | |
| 70 | + | |
| 71 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; | |
| 4 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; | |
| 5 | +import org.flowable.task.service.impl.persistence.entity.TaskEntity; | |
| 6 | +import org.springframework.stereotype.Component; | |
| 7 | + | |
| 8 | +import java.util.Set; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * 分配给发起人的一级 Leader 审批的 Script 实现类 | |
| 12 | + * | |
| 13 | + * @author 芋道源码 | |
| 14 | + */ | |
| 15 | +@Component | |
| 16 | +public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript { | |
| 17 | + | |
| 18 | + @Override | |
| 19 | + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据 | |
| 20 | + public Set<Long> calculateTaskCandidateUsers(TaskEntity task) { | |
| 21 | + return calculateTaskCandidateUsers(task, 1); | |
| 22 | + } | |
| 23 | + | |
| 24 | + @Override | |
| 25 | + public BpmTaskRuleScriptEnum getEnum() { | |
| 26 | + return BpmTaskRuleScriptEnum.LEADER_X1; | |
| 27 | + } | |
| 28 | + | |
| 29 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; | |
| 4 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; | |
| 5 | +import org.flowable.task.service.impl.persistence.entity.TaskEntity; | |
| 6 | +import org.springframework.stereotype.Component; | |
| 7 | + | |
| 8 | +import java.util.Set; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * 分配给发起人的二级 Leader 审批的 Script 实现类 | |
| 12 | + * | |
| 13 | + * @author 芋道源码 | |
| 14 | + */ | |
| 15 | +@Component | |
| 16 | +public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript { | |
| 17 | + | |
| 18 | + @Override | |
| 19 | + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据 | |
| 20 | + public Set<Long> calculateTaskCandidateUsers(TaskEntity task) { | |
| 21 | + return calculateTaskCandidateUsers(task, 2); | |
| 22 | + } | |
| 23 | + | |
| 24 | + @Override | |
| 25 | + public BpmTaskRuleScriptEnum getEnum() { | |
| 26 | + return BpmTaskRuleScriptEnum.LEADER_X2; | |
| 27 | + } | |
| 28 | + | |
| 29 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; | |
| 6 | + | |
| 7 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; | |
| 8 | +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; | |
| 9 | +import org.flowable.engine.runtime.ProcessInstance; | |
| 10 | +import org.flowable.task.service.impl.persistence.entity.TaskEntity; | |
| 11 | +import org.springframework.context.annotation.Lazy; | |
| 12 | +import org.springframework.stereotype.Component; | |
| 13 | + | |
| 14 | +import javax.annotation.Resource; | |
| 15 | +import java.util.Set; | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * 分配给发起人审批的 Script 实现类 | |
| 19 | + * | |
| 20 | + * @author 芋道源码 | |
| 21 | + */ | |
| 22 | +@Component | |
| 23 | +public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript { | |
| 24 | + | |
| 25 | + @Resource | |
| 26 | + @Lazy // 解决循环依赖 | |
| 27 | + private BpmProcessInstanceService bpmProcessInstanceService; | |
| 28 | + | |
| 29 | + @Override | |
| 30 | + public Set<Long> calculateTaskCandidateUsers(TaskEntity task) { | |
| 31 | + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId()); | |
| 32 | + Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); | |
| 33 | + return SetUtils.asSet(startUserId); | |
| 34 | + } | |
| 35 | + | |
| 36 | + @Override | |
| 37 | + public BpmTaskRuleScriptEnum getEnum() { | |
| 38 | + return BpmTaskRuleScriptEnum.START_USER; | |
| 39 | + } | |
| 40 | + | |
| 41 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; | |
| 5 | +import com.google.common.collect.ImmutableSet; | |
| 6 | +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; | |
| 7 | +import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; | |
| 8 | +import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener; | |
| 9 | +import org.flowable.engine.delegate.event.FlowableCancelledEvent; | |
| 10 | +import org.flowable.engine.delegate.event.FlowableProcessStartedEvent; | |
| 11 | +import org.flowable.engine.runtime.ProcessInstance; | |
| 12 | +import org.springframework.context.annotation.Lazy; | |
| 13 | +import org.springframework.stereotype.Component; | |
| 14 | + | |
| 15 | +import javax.annotation.Resource; | |
| 16 | +import java.util.Set; | |
| 17 | +/** | |
| 18 | + * 监听 {@link ProcessInstance} 的开始与完成,创建与更新对应的 {@link BpmProcessInstanceExtDO} 记录 | |
| 19 | + * | |
| 20 | + * @author jason | |
| 21 | + */ | |
| 22 | +@Component | |
| 23 | +public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEventListener { | |
| 24 | + | |
| 25 | + @Resource | |
| 26 | + @Lazy | |
| 27 | + private BpmProcessInstanceService processInstanceService; | |
| 28 | + | |
| 29 | + public static final Set<FlowableEngineEventType> PROCESS_INSTANCE_EVENTS = ImmutableSet.<FlowableEngineEventType>builder() | |
| 30 | + .add(FlowableEngineEventType.PROCESS_CREATED) | |
| 31 | + .add(FlowableEngineEventType.PROCESS_CANCELLED) | |
| 32 | + .add(FlowableEngineEventType.PROCESS_COMPLETED) | |
| 33 | + .build(); | |
| 34 | + | |
| 35 | + public BpmProcessInstanceEventListener(){ | |
| 36 | + super(PROCESS_INSTANCE_EVENTS); | |
| 37 | + } | |
| 38 | + | |
| 39 | + @Override | |
| 40 | + protected void processCreated(FlowableEngineEntityEvent event) { | |
| 41 | + processInstanceService.createProcessInstanceExt((ProcessInstance)event.getEntity()); | |
| 42 | + } | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + protected void processCancelled(FlowableCancelledEvent event) { | |
| 46 | + processInstanceService.updateProcessInstanceExtCancel(event); | |
| 47 | + } | |
| 48 | + | |
| 49 | + @Override | |
| 50 | + protected void processCompleted(FlowableEngineEntityEvent event) { | |
| 51 | + processInstanceService.updateProcessInstanceExtComplete((ProcessInstance)event.getEntity()); | |
| 52 | + } | |
| 53 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; | |
| 5 | +import com.google.common.collect.ImmutableSet; | |
| 6 | +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; | |
| 7 | +import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; | |
| 8 | +import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener; | |
| 9 | +import org.flowable.task.api.Task; | |
| 10 | +import org.springframework.context.annotation.Lazy; | |
| 11 | +import org.springframework.stereotype.Component; | |
| 12 | + | |
| 13 | +import javax.annotation.Resource; | |
| 14 | +import java.util.Set; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * 监听 {@link org.flowable.task.api.Task} 的开始与完成,创建与更新对应的 {@link BpmTaskExtDO} 记录 | |
| 18 | + * | |
| 19 | + * @author jason | |
| 20 | + */ | |
| 21 | +@Component | |
| 22 | +public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { | |
| 23 | + | |
| 24 | + @Resource | |
| 25 | + @Lazy // 解决循环依赖 | |
| 26 | + private BpmTaskService taskService; | |
| 27 | + | |
| 28 | + public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder() | |
| 29 | + .add(FlowableEngineEventType.TASK_CREATED) | |
| 30 | + .add(FlowableEngineEventType.TASK_ASSIGNED) | |
| 31 | + .add(FlowableEngineEventType.TASK_COMPLETED) | |
| 32 | + .build(); | |
| 33 | + | |
| 34 | + public BpmTaskEventListener(){ | |
| 35 | + super(TASK_EVENTS); | |
| 36 | + } | |
| 37 | + | |
| 38 | + @Override | |
| 39 | + protected void taskCreated(FlowableEngineEntityEvent event) { | |
| 40 | + taskService.createTaskExt((Task) event.getEntity()); | |
| 41 | + } | |
| 42 | + | |
| 43 | + @Override | |
| 44 | + protected void taskCompleted(FlowableEngineEntityEvent event) { | |
| 45 | + taskService.updateTaskExtComplete((Task)event.getEntity()); | |
| 46 | + } | |
| 47 | + | |
| 48 | + @Override | |
| 49 | + protected void taskAssigned(FlowableEngineEntityEvent event) { | |
| 50 | + taskService.updateTaskExtAssign((Task)event.getEntity()); | |
| 51 | + } | |
| 52 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java
0 → 100644
| 1 | +/** | |
| 2 | + * bpm 包下,业务流程管理(Business Process Management),我们放工作流的功能,基于 activiti 7 版本实现。 | |
| 3 | + * 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等 | |
| 4 | + * | |
| 5 | + * bpm 解释:https://baike.baidu.com/item/BPM/1933 | |
| 6 | + * | |
| 7 | + * 1. Controller URL:以 /bpm/ 开头,避免和其它 Module 冲突 | |
| 8 | + * 2. DataObject 表名:以 bpm_ 开头,方便在数据库中区分 | |
| 9 | + * | |
| 10 | + * 注意,由于 Bpm 模块下,容易和其它模块重名,所以类名都加载 Pay 的前缀~ | |
| 11 | + */ | |
| 12 | +package cn.iocoder.yudao.module.bpm; | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 8 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 9 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 10 | + | |
| 11 | +import javax.validation.Valid; | |
| 12 | +import java.util.Collection; | |
| 13 | +import java.util.Collections; | |
| 14 | +import java.util.List; | |
| 15 | +import java.util.Map; | |
| 16 | + | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * 动态表单 Service 接口 | |
| 20 | + * | |
| 21 | + * @author @风里雾里 | |
| 22 | + */ | |
| 23 | +public interface BpmFormService { | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * 创建动态表单 | |
| 27 | + * | |
| 28 | + * @param createReqVO 创建信息 | |
| 29 | + * @return 编号 | |
| 30 | + */ | |
| 31 | + Long createForm(@Valid BpmFormCreateReqVO createReqVO); | |
| 32 | + | |
| 33 | + /** | |
| 34 | + * 更新动态表单 | |
| 35 | + * | |
| 36 | + * @param updateReqVO 更新信息 | |
| 37 | + */ | |
| 38 | + void updateForm(@Valid BpmFormUpdateReqVO updateReqVO); | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * 删除动态表单 | |
| 42 | + * | |
| 43 | + * @param id 编号 | |
| 44 | + */ | |
| 45 | + void deleteForm(Long id); | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * 获得动态表单 | |
| 49 | + * | |
| 50 | + * @param id 编号 | |
| 51 | + * @return 动态表单 | |
| 52 | + */ | |
| 53 | + BpmFormDO getForm(Long id); | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * 获得动态表单列表 | |
| 57 | + * | |
| 58 | + * @return 动态表单列表 | |
| 59 | + */ | |
| 60 | + List<BpmFormDO> getFormList(); | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * 获得动态表单列表 | |
| 64 | + * | |
| 65 | + * @param ids 编号 | |
| 66 | + * @return 动态表单列表 | |
| 67 | + */ | |
| 68 | + List<BpmFormDO> getFormList(Collection<Long> ids); | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * 获得动态表单 Map | |
| 72 | + * | |
| 73 | + * @param ids 编号 | |
| 74 | + * @return 动态表单 Map | |
| 75 | + */ | |
| 76 | + default Map<Long, BpmFormDO> getFormMap(Collection<Long> ids) { | |
| 77 | + if (CollUtil.isEmpty(ids)) { | |
| 78 | + return Collections.emptyMap(); | |
| 79 | + } | |
| 80 | + return CollectionUtils.convertMap(this.getFormList(ids), BpmFormDO::getId); | |
| 81 | + } | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * 获得动态表单分页 | |
| 85 | + * | |
| 86 | + * @param pageReqVO 分页查询 | |
| 87 | + * @return 动态表单分页 | |
| 88 | + */ | |
| 89 | + PageResult<BpmFormDO> getFormPage(BpmFormPageReqVO pageReqVO); | |
| 90 | + | |
| 91 | + /** | |
| 92 | + * 校验流程表单已配置 | |
| 93 | + * | |
| 94 | + * @param configStr configStr 字段 | |
| 95 | + * @return 流程表单 | |
| 96 | + */ | |
| 97 | + BpmFormDO checkFormConfig(String configStr); | |
| 98 | + | |
| 99 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.hutool.core.lang.Assert; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.convert.definition.BpmFormConvert; | |
| 9 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 10 | +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmFormMapper; | |
| 11 | +import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants; | |
| 12 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; | |
| 13 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmFormFieldRespDTO; | |
| 14 | +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | |
| 15 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 16 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 17 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; | |
| 18 | +import org.springframework.stereotype.Service; | |
| 19 | +import org.springframework.validation.annotation.Validated; | |
| 20 | + | |
| 21 | +import javax.annotation.Resource; | |
| 22 | +import java.util.*; | |
| 23 | + | |
| 24 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 25 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * 动态表单 Service 实现类 | |
| 29 | + * | |
| 30 | + * @author 风里雾里 | |
| 31 | + */ | |
| 32 | +@Service | |
| 33 | +@Validated | |
| 34 | +public class BpmFormServiceImpl implements BpmFormService { | |
| 35 | + | |
| 36 | + @Resource | |
| 37 | + private BpmFormMapper formMapper; | |
| 38 | + | |
| 39 | + @Override | |
| 40 | + public Long createForm(BpmFormCreateReqVO createReqVO) { | |
| 41 | + this.checkFields(createReqVO.getFields()); | |
| 42 | + // 插入 | |
| 43 | + BpmFormDO form = BpmFormConvert.INSTANCE.convert(createReqVO); | |
| 44 | + formMapper.insert(form); | |
| 45 | + // 返回 | |
| 46 | + return form.getId(); | |
| 47 | + } | |
| 48 | + | |
| 49 | + @Override | |
| 50 | + public void updateForm(BpmFormUpdateReqVO updateReqVO) { | |
| 51 | + this.checkFields(updateReqVO.getFields()); | |
| 52 | + // 校验存在 | |
| 53 | + this.validateFormExists(updateReqVO.getId()); | |
| 54 | + // 更新 | |
| 55 | + BpmFormDO updateObj = BpmFormConvert.INSTANCE.convert(updateReqVO); | |
| 56 | + formMapper.updateById(updateObj); | |
| 57 | + } | |
| 58 | + | |
| 59 | + @Override | |
| 60 | + public void deleteForm(Long id) { | |
| 61 | + // 校验存在 | |
| 62 | + this.validateFormExists(id); | |
| 63 | + // 删除 | |
| 64 | + formMapper.deleteById(id); | |
| 65 | + } | |
| 66 | + | |
| 67 | + private void validateFormExists(Long id) { | |
| 68 | + if (formMapper.selectById(id) == null) { | |
| 69 | + throw ServiceExceptionUtil.exception(ErrorCodeConstants.FORM_NOT_EXISTS); | |
| 70 | + } | |
| 71 | + } | |
| 72 | + | |
| 73 | + @Override | |
| 74 | + public BpmFormDO getForm(Long id) { | |
| 75 | + return formMapper.selectById(id); | |
| 76 | + } | |
| 77 | + | |
| 78 | + @Override | |
| 79 | + public List<BpmFormDO> getFormList() { | |
| 80 | + return formMapper.selectList(); | |
| 81 | + } | |
| 82 | + | |
| 83 | + @Override | |
| 84 | + public List<BpmFormDO> getFormList(Collection<Long> ids) { | |
| 85 | + return formMapper.selectBatchIds(ids); | |
| 86 | + } | |
| 87 | + | |
| 88 | + @Override | |
| 89 | + public PageResult<BpmFormDO> getFormPage(BpmFormPageReqVO pageReqVO) { | |
| 90 | + return formMapper.selectPage(pageReqVO); | |
| 91 | + } | |
| 92 | + | |
| 93 | + | |
| 94 | + @Override | |
| 95 | + public BpmFormDO checkFormConfig(String configStr) { | |
| 96 | + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(configStr, BpmModelMetaInfoRespDTO.class); | |
| 97 | + if (metaInfo == null || metaInfo.getFormType() == null) { | |
| 98 | + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); | |
| 99 | + } | |
| 100 | + // 校验表单存在 | |
| 101 | + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) { | |
| 102 | + BpmFormDO form = getForm(metaInfo.getFormId()); | |
| 103 | + if (form == null) { | |
| 104 | + throw exception(FORM_NOT_EXISTS); | |
| 105 | + } | |
| 106 | + return form; | |
| 107 | + } | |
| 108 | + return null; | |
| 109 | + } | |
| 110 | + | |
| 111 | + private void checkKeyNCName(String key) { | |
| 112 | + if (!ValidationUtils.isXmlNCName(key)) { | |
| 113 | + throw exception(MODEL_KEY_VALID); | |
| 114 | + } | |
| 115 | + } | |
| 116 | + /** | |
| 117 | + * 校验 Field,避免 field 重复 | |
| 118 | + * | |
| 119 | + * @param fields field 数组 | |
| 120 | + */ | |
| 121 | + private void checkFields(List<String> fields) { | |
| 122 | + Map<String, String> fieldMap = new HashMap<>(); // key 是 vModel,value 是 label | |
| 123 | + for (String field : fields) { | |
| 124 | + BpmFormFieldRespDTO fieldDTO = JsonUtils.parseObject(field, BpmFormFieldRespDTO.class); | |
| 125 | + Assert.notNull(fieldDTO); | |
| 126 | + String oldLabel = fieldMap.put(fieldDTO.getVModel(), fieldDTO.getLabel()); | |
| 127 | + // 如果不存在,则直接返回 | |
| 128 | + if (oldLabel == null) { | |
| 129 | + continue; | |
| 130 | + } | |
| 131 | + // 如果存在,则报错 | |
| 132 | + throw ServiceExceptionUtil.exception(ErrorCodeConstants.FORM_FIELD_REPEAT, oldLabel, fieldDTO.getLabel(), fieldDTO.getVModel()); | |
| 133 | + } | |
| 134 | + } | |
| 135 | + | |
| 136 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; | |
| 5 | +import org.flowable.bpmn.model.BpmnModel; | |
| 6 | + | |
| 7 | +import javax.validation.Valid; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * Flowable流程模型接口 | |
| 11 | + * | |
| 12 | + * @author yunlongn | |
| 13 | + */ | |
| 14 | +public interface BpmModelService { | |
| 15 | + /** | |
| 16 | + * 获得流程模型分页 | |
| 17 | + * | |
| 18 | + * @param pageVO 分页查询 | |
| 19 | + * @return 流程模型分页 | |
| 20 | + */ | |
| 21 | + PageResult<BpmModelPageItemRespVO> getModelPage(BpmModelPageReqVO pageVO); | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * 创建流程模型 | |
| 25 | + * | |
| 26 | + * @param modelVO 创建信息 | |
| 27 | + * @param bpmnXml BPMN XML | |
| 28 | + * @return 创建的流程模型的编号 | |
| 29 | + */ | |
| 30 | + String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml); | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * 获得流程模块 | |
| 34 | + * | |
| 35 | + * @param id 编号 | |
| 36 | + * @return 流程模型 | |
| 37 | + */ | |
| 38 | + BpmModelRespVO getModel(String id); | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * 修改流程模型 | |
| 42 | + * | |
| 43 | + * @param updateReqVO 更新信息 | |
| 44 | + */ | |
| 45 | + void updateModel(@Valid BpmModelUpdateReqVO updateReqVO); | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * 将流程模型,部署成一个流程定义 | |
| 49 | + * | |
| 50 | + * @param id 编号 | |
| 51 | + */ | |
| 52 | + void deployModel(String id); | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * 删除模型 | |
| 56 | + * | |
| 57 | + * @param id 编号 | |
| 58 | + */ | |
| 59 | + void deleteModel(String id); | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * 修改模型的状态,实际更新的部署的流程定义的状态 | |
| 63 | + * | |
| 64 | + * @param id 编号 | |
| 65 | + * @param state 状态 | |
| 66 | + */ | |
| 67 | + void updateModelState(String id, Integer state); | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * 获得流程模型编号对应的 BPMN Model | |
| 71 | + * | |
| 72 | + * @param id 流程模型编号 | |
| 73 | + * @return BPMN Model | |
| 74 | + */ | |
| 75 | + BpmnModel getBpmnModel(String id); | |
| 76 | + | |
| 77 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.ArrayUtil; | |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 7 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 8 | +import cn.iocoder.yudao.framework.common.util.object.PageUtils; | |
| 9 | +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | |
| 10 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; | |
| 11 | +import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert; | |
| 12 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 13 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; | |
| 14 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; | |
| 15 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; | |
| 16 | +import lombok.extern.slf4j.Slf4j; | |
| 17 | +import org.flowable.bpmn.converter.BpmnXMLConverter; | |
| 18 | +import org.flowable.bpmn.model.BpmnModel; | |
| 19 | +import org.flowable.common.engine.impl.db.SuspensionState; | |
| 20 | +import org.flowable.common.engine.impl.util.io.BytesStreamSource; | |
| 21 | +import org.flowable.engine.RepositoryService; | |
| 22 | +import org.flowable.engine.repository.Deployment; | |
| 23 | +import org.flowable.engine.repository.Model; | |
| 24 | +import org.flowable.engine.repository.ModelQuery; | |
| 25 | +import org.flowable.engine.repository.ProcessDefinition; | |
| 26 | +import org.springframework.stereotype.Service; | |
| 27 | +import org.springframework.transaction.annotation.Transactional; | |
| 28 | +import org.springframework.util.ObjectUtils; | |
| 29 | +import org.springframework.validation.annotation.Validated; | |
| 30 | + | |
| 31 | +import javax.annotation.Resource; | |
| 32 | +import javax.validation.Valid; | |
| 33 | +import java.util.*; | |
| 34 | + | |
| 35 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 36 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | |
| 37 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * Flowable流程模型实现 | |
| 41 | + * 主要进行 Flowable {@link Model} 的维护 | |
| 42 | + * | |
| 43 | + * @author yunlongn | |
| 44 | + * @author 芋道源码 | |
| 45 | + * @author jason | |
| 46 | + */ | |
| 47 | +@Service | |
| 48 | +@Validated | |
| 49 | +@Slf4j | |
| 50 | +public class BpmModelServiceImpl implements BpmModelService { | |
| 51 | + | |
| 52 | + @Resource | |
| 53 | + private RepositoryService repositoryService; | |
| 54 | + @Resource | |
| 55 | + private BpmProcessDefinitionService processDefinitionService; | |
| 56 | + @Resource | |
| 57 | + private BpmFormService bpmFormService; | |
| 58 | + @Resource | |
| 59 | + private BpmTaskAssignRuleService taskAssignRuleService; | |
| 60 | + | |
| 61 | + @Override | |
| 62 | + public PageResult<BpmModelPageItemRespVO> getModelPage(BpmModelPageReqVO pageVO) { | |
| 63 | + ModelQuery modelQuery = repositoryService.createModelQuery(); | |
| 64 | + if (StrUtil.isNotBlank(pageVO.getKey())) { | |
| 65 | + modelQuery.modelKey(pageVO.getKey()); | |
| 66 | + } | |
| 67 | + if (StrUtil.isNotBlank(pageVO.getName())) { | |
| 68 | + modelQuery.modelNameLike("%" + pageVO.getName() + "%"); // 模糊匹配 | |
| 69 | + } | |
| 70 | + if (StrUtil.isNotBlank(pageVO.getCategory())) { | |
| 71 | + modelQuery.modelCategory(pageVO.getCategory()); | |
| 72 | + } | |
| 73 | + // 执行查询 | |
| 74 | + List<Model> models = modelQuery.orderByCreateTime().desc() | |
| 75 | + .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); | |
| 76 | + | |
| 77 | + // 获得 Form Map | |
| 78 | + Set<Long> formIds = CollectionUtils.convertSet(models, model -> { | |
| 79 | + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); | |
| 80 | + return metaInfo != null ? metaInfo.getFormId() : null; | |
| 81 | + }); | |
| 82 | + Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds); | |
| 83 | + | |
| 84 | + // 获得 Deployment Map | |
| 85 | + Set<String> deploymentIds = new HashSet<>(); | |
| 86 | + models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId())); | |
| 87 | + Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds); | |
| 88 | + // 获得 ProcessDefinition Map | |
| 89 | + List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds); | |
| 90 | + Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId); | |
| 91 | + | |
| 92 | + // 拼接结果 | |
| 93 | + long modelCount = modelQuery.count(); | |
| 94 | + return new PageResult<>(BpmModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount); | |
| 95 | + } | |
| 96 | + | |
| 97 | + @Override | |
| 98 | + @Transactional(rollbackFor = Exception.class) | |
| 99 | + public String createModel(@Valid BpmModelCreateReqVO createReqVO, String bpmnXml) { | |
| 100 | + checkKeyNCName(createReqVO.getKey()); | |
| 101 | + // 校验流程标识已经存在 | |
| 102 | + Model keyModel = this.getModelByKey(createReqVO.getKey()); | |
| 103 | + if (keyModel != null) { | |
| 104 | + throw exception(MODEL_KEY_EXISTS, createReqVO.getKey()); | |
| 105 | + } | |
| 106 | + | |
| 107 | + // 创建流程定义 | |
| 108 | + Model model = repositoryService.newModel(); | |
| 109 | + BpmModelConvert.INSTANCE.copy(model, createReqVO); | |
| 110 | + // 保存流程定义 | |
| 111 | + repositoryService.saveModel(model); | |
| 112 | + // 保存 BPMN XML | |
| 113 | + saveModelBpmnXml(model, bpmnXml); | |
| 114 | + return model.getId(); | |
| 115 | + } | |
| 116 | + | |
| 117 | + private Model getModelByKey(String key) { | |
| 118 | + return repositoryService.createModelQuery().modelKey(key).singleResult(); | |
| 119 | + } | |
| 120 | + | |
| 121 | + @Override | |
| 122 | + public BpmModelRespVO getModel(String id) { | |
| 123 | + Model model = repositoryService.getModel(id); | |
| 124 | + if (model == null) { | |
| 125 | + return null; | |
| 126 | + } | |
| 127 | + BpmModelRespVO modelRespVO = BpmModelConvert.INSTANCE.convert(model); | |
| 128 | + // 拼接 bpmn XML | |
| 129 | + byte[] bpmnBytes = repositoryService.getModelEditorSource(id); | |
| 130 | + modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes)); | |
| 131 | + return modelRespVO; | |
| 132 | + } | |
| 133 | + | |
| 134 | + @Override | |
| 135 | + @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务 | |
| 136 | + public void updateModel(@Valid BpmModelUpdateReqVO updateReqVO) { | |
| 137 | + // 校验流程模型存在 | |
| 138 | + Model model = repositoryService.getModel(updateReqVO.getId()); | |
| 139 | + if (model == null) { | |
| 140 | + throw exception(MODEL_NOT_EXISTS); | |
| 141 | + } | |
| 142 | + | |
| 143 | + // 修改流程定义 | |
| 144 | + BpmModelConvert.INSTANCE.copy(model, updateReqVO); | |
| 145 | + // 更新模型 | |
| 146 | + repositoryService.saveModel(model); | |
| 147 | + // 更新 BPMN XML | |
| 148 | + saveModelBpmnXml(model, updateReqVO.getBpmnXml()); | |
| 149 | + } | |
| 150 | + | |
| 151 | + @Override | |
| 152 | + @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务 | |
| 153 | + public void deployModel(String id) { | |
| 154 | + // 校验流程模型存在 | |
| 155 | + Model model = repositoryService.getModel(id); | |
| 156 | + if (ObjectUtils.isEmpty(model)) { | |
| 157 | + throw exception(MODEL_NOT_EXISTS); | |
| 158 | + } | |
| 159 | + // 校验流程图 | |
| 160 | + byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId()); | |
| 161 | + if (bpmnBytes == null) { | |
| 162 | + throw exception(MODEL_NOT_EXISTS); | |
| 163 | + } | |
| 164 | + // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素; | |
| 165 | + // 校验表单已配 | |
| 166 | + BpmFormDO form = checkFormConfig(model.getMetaInfo()); | |
| 167 | + //校验任务分配规则已配置 | |
| 168 | + taskAssignRuleService.checkTaskAssignRuleAllConfig(id); | |
| 169 | + | |
| 170 | + BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes); | |
| 171 | + //校验模型是否发生修改。如果未修改,则不允许创建 | |
| 172 | + if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等 | |
| 173 | + ProcessDefinition oldProcessInstance = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId()); | |
| 174 | + if (oldProcessInstance != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessInstance.getId())) { | |
| 175 | + throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS); | |
| 176 | + } | |
| 177 | + } | |
| 178 | + // 创建流程定义 | |
| 179 | + String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO); | |
| 180 | + | |
| 181 | + // 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。 | |
| 182 | + updateProcessDefinitionSuspended(model.getDeploymentId()); | |
| 183 | + | |
| 184 | + // 更新 model 的 deploymentId,进行关联 | |
| 185 | + ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId); | |
| 186 | + model.setDeploymentId(definition.getDeploymentId()); | |
| 187 | + repositoryService.saveModel(model); | |
| 188 | + | |
| 189 | + //复制任务分配规则 | |
| 190 | + taskAssignRuleService.copyTaskAssignRules(id, definition.getId()); | |
| 191 | + } | |
| 192 | + | |
| 193 | + | |
| 194 | + @Override | |
| 195 | + @Transactional(rollbackFor = Exception.class) | |
| 196 | + public void deleteModel(String id) { | |
| 197 | + // 校验流程模型存在 | |
| 198 | + Model model = repositoryService.getModel(id); | |
| 199 | + if (model == null) { | |
| 200 | + throw exception(MODEL_NOT_EXISTS); | |
| 201 | + } | |
| 202 | + // 执行删除 | |
| 203 | + repositoryService.deleteModel(id); | |
| 204 | + // 禁用流程实例 | |
| 205 | + updateProcessDefinitionSuspended(model.getDeploymentId()); | |
| 206 | + } | |
| 207 | + | |
| 208 | + @Override | |
| 209 | + public void updateModelState(String id, Integer state) { | |
| 210 | + // 校验流程模型存在 | |
| 211 | + Model model = repositoryService.getModel(id); | |
| 212 | + if (model == null) { | |
| 213 | + throw exception(MODEL_NOT_EXISTS); | |
| 214 | + } | |
| 215 | + // 校验流程定义存在 | |
| 216 | + ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId()); | |
| 217 | + if (definition == null) { | |
| 218 | + throw exception(PROCESS_DEFINITION_NOT_EXISTS); | |
| 219 | + } | |
| 220 | + | |
| 221 | + // 更新状态 | |
| 222 | + processDefinitionService.updateProcessDefinitionState(definition.getId(), state); | |
| 223 | + } | |
| 224 | + | |
| 225 | + @Override | |
| 226 | + public BpmnModel getBpmnModel(String id) { | |
| 227 | + byte[] bpmnBytes = repositoryService.getModelEditorSource(id); | |
| 228 | + if (ArrayUtil.isEmpty(bpmnBytes)) { | |
| 229 | + return null; | |
| 230 | + } | |
| 231 | + BpmnXMLConverter converter = new BpmnXMLConverter(); | |
| 232 | + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true); | |
| 233 | + } | |
| 234 | + | |
| 235 | + private void checkKeyNCName(String key) { | |
| 236 | + if (!ValidationUtils.isXmlNCName(key)) { | |
| 237 | + throw exception(MODEL_KEY_VALID); | |
| 238 | + } | |
| 239 | + } | |
| 240 | + | |
| 241 | + /** | |
| 242 | + * 校验流程表单已配置 | |
| 243 | + * | |
| 244 | + * @param metaInfoStr 流程模型 metaInfo 字段 | |
| 245 | + * @return 流程表单 | |
| 246 | + */ | |
| 247 | + private BpmFormDO checkFormConfig(String metaInfoStr) { | |
| 248 | + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(metaInfoStr, BpmModelMetaInfoRespDTO.class); | |
| 249 | + if (metaInfo == null || metaInfo.getFormType() == null) { | |
| 250 | + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); | |
| 251 | + } | |
| 252 | + // 校验表单存在 | |
| 253 | + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) { | |
| 254 | + BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId()); | |
| 255 | + if (form == null) { | |
| 256 | + throw exception(FORM_NOT_EXISTS); | |
| 257 | + } | |
| 258 | + return form; | |
| 259 | + } | |
| 260 | + return null; | |
| 261 | + } | |
| 262 | + | |
| 263 | + private void saveModelBpmnXml(Model model, String bpmnXml) { | |
| 264 | + if (StrUtil.isEmpty(bpmnXml)) { | |
| 265 | + return; | |
| 266 | + } | |
| 267 | + repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml)); | |
| 268 | + } | |
| 269 | + | |
| 270 | + /** | |
| 271 | + * 挂起 deploymentId 对应的流程定义。 这里一个deploymentId 只关联一个流程定义 | |
| 272 | + * @param deploymentId 流程发布Id. | |
| 273 | + */ | |
| 274 | + private void updateProcessDefinitionSuspended(String deploymentId) { | |
| 275 | + if (StrUtil.isEmpty(deploymentId)) { | |
| 276 | + return; | |
| 277 | + } | |
| 278 | + ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(deploymentId); | |
| 279 | + if (oldDefinition == null) { | |
| 280 | + return; | |
| 281 | + } | |
| 282 | + processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode()); | |
| 283 | + } | |
| 284 | + | |
| 285 | + | |
| 286 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; | |
| 10 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; | |
| 11 | +import org.flowable.bpmn.model.BpmnModel; | |
| 12 | +import org.flowable.engine.repository.Deployment; | |
| 13 | +import org.flowable.engine.repository.ProcessDefinition; | |
| 14 | + | |
| 15 | +import javax.validation.Valid; | |
| 16 | +import java.util.List; | |
| 17 | +import java.util.Map; | |
| 18 | +import java.util.Set; | |
| 19 | +/** | |
| 20 | + * Flowable流程定义接口 | |
| 21 | + * | |
| 22 | + * @author yunlong.li | |
| 23 | + * @author ZJQ | |
| 24 | + * @author 芋道源码 | |
| 25 | + */ | |
| 26 | +public interface BpmProcessDefinitionService { | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 获得流程定义分页 | |
| 30 | + * | |
| 31 | + * @param pageReqVO 分页入参 | |
| 32 | + * @return 流程定义 Page | |
| 33 | + */ | |
| 34 | + PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO); | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * 获得流程定义列表 | |
| 38 | + * | |
| 39 | + * @param listReqVO 列表入参 | |
| 40 | + * @return 流程定义列表 | |
| 41 | + */ | |
| 42 | + List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO); | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * 创建流程定义 | |
| 46 | + * | |
| 47 | + * @param createReqDTO 创建信息 | |
| 48 | + * @return 流程编号 | |
| 49 | + */ | |
| 50 | + String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * 更新流程定义状态 | |
| 54 | + * | |
| 55 | + * @param id 流程定义的编号 | |
| 56 | + * @param state 状态 | |
| 57 | + */ | |
| 58 | + void updateProcessDefinitionState(String id, Integer state); | |
| 59 | + | |
| 60 | + /** | |
| 61 | + * 获得流程定义对应的 BPMN XML | |
| 62 | + * | |
| 63 | + * @param id 流程定义编号 | |
| 64 | + * @return BPMN XML | |
| 65 | + */ | |
| 66 | + String getProcessDefinitionBpmnXML(String id); | |
| 67 | + | |
| 68 | + /** | |
| 69 | + * 获得需要创建的流程定义,是否和当前激活的流程定义相等 | |
| 70 | + * | |
| 71 | + * @param createReqDTO 创建信息 | |
| 72 | + * @return 是否相等 | |
| 73 | + */ | |
| 74 | + boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * 获得编号对应的 BpmProcessDefinitionExtDO | |
| 78 | + * | |
| 79 | + * @param id 编号 | |
| 80 | + * @return 流程定义拓展 | |
| 81 | + */ | |
| 82 | + BpmProcessDefinitionExtDO getProcessDefinitionExt(String id); | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * 获得编号对应的 ProcessDefinition | |
| 86 | + * | |
| 87 | + * @param id 编号 | |
| 88 | + * @return 流程定义 | |
| 89 | + */ | |
| 90 | + ProcessDefinition getProcessDefinition(String id); | |
| 91 | + | |
| 92 | + /** | |
| 93 | + * 获得编号对应的 ProcessDefinition | |
| 94 | + * | |
| 95 | + * 相比 {@link #getProcessDefinition(String)} 方法,category 的取值是正确 | |
| 96 | + * | |
| 97 | + * @param id 编号 | |
| 98 | + * @return 流程定义 | |
| 99 | + */ | |
| 100 | + ProcessDefinition getProcessDefinition2(String id); | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * 获得 deploymentId 对应的 ProcessDefinition | |
| 104 | + * | |
| 105 | + * @param deploymentId 部署编号 | |
| 106 | + * @return 流程定义 | |
| 107 | + */ | |
| 108 | + ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId); | |
| 109 | + | |
| 110 | + /** | |
| 111 | + * 获得 deploymentIds 对应的 ProcessDefinition 数组 | |
| 112 | + * | |
| 113 | + * @param deploymentIds 部署编号的数组 | |
| 114 | + * @return 流程定义的数组 | |
| 115 | + */ | |
| 116 | + List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds); | |
| 117 | + | |
| 118 | + /** | |
| 119 | + * 获得流程定义标识对应的激活的流程定义 | |
| 120 | + * | |
| 121 | + * @param key 流程定义的标识 | |
| 122 | + * @return 流程定义 | |
| 123 | + */ | |
| 124 | + ProcessDefinition getActiveProcessDefinition(String key); | |
| 125 | + | |
| 126 | + /** | |
| 127 | + * 获得 ids 对应的 Deployment Map | |
| 128 | + * | |
| 129 | + * @param ids 部署编号的数组 | |
| 130 | + * @return 流程部署 Map | |
| 131 | + */ | |
| 132 | + default Map<String, Deployment> getDeploymentMap(Set<String> ids) { | |
| 133 | + return CollectionUtils.convertMap(getDeployments(ids), Deployment::getId); | |
| 134 | + } | |
| 135 | + | |
| 136 | + /** | |
| 137 | + * 获得 ids 对应的 Deployment 数组 | |
| 138 | + * | |
| 139 | + * @param ids 部署编号的数组 | |
| 140 | + * @return 流程部署的数组 | |
| 141 | + */ | |
| 142 | + List<Deployment> getDeployments(Set<String> ids); | |
| 143 | + | |
| 144 | + /** | |
| 145 | + * 获得 id 对应的 Deployment | |
| 146 | + * | |
| 147 | + * @param id 部署编号 | |
| 148 | + * @return 流程部署 | |
| 149 | + */ | |
| 150 | + Deployment getDeployment(String id); | |
| 151 | + | |
| 152 | + /** | |
| 153 | + * 获得 Bpmn 模型 | |
| 154 | + * | |
| 155 | + * @param processDefinitionId 流程定义的编号 | |
| 156 | + * @return Bpmn 模型 | |
| 157 | + */ | |
| 158 | + BpmnModel getBpmnModel(String processDefinitionId); | |
| 159 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.util.ObjectUtil; | |
| 5 | +import cn.hutool.core.util.StrUtil; | |
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 7 | +import cn.iocoder.yudao.framework.common.util.object.PageUtils; | |
| 8 | +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; | |
| 9 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO; | |
| 10 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; | |
| 11 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; | |
| 12 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; | |
| 13 | +import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; | |
| 14 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 15 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; | |
| 16 | +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; | |
| 17 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; | |
| 18 | +import lombok.extern.slf4j.Slf4j; | |
| 19 | +import org.flowable.bpmn.converter.BpmnXMLConverter; | |
| 20 | +import org.flowable.bpmn.model.BpmnModel; | |
| 21 | +import org.flowable.common.engine.impl.db.SuspensionState; | |
| 22 | +import org.flowable.common.engine.impl.util.io.BytesStreamSource; | |
| 23 | +import org.flowable.engine.RepositoryService; | |
| 24 | +import org.flowable.engine.repository.Deployment; | |
| 25 | +import org.flowable.engine.repository.ProcessDefinition; | |
| 26 | +import org.flowable.engine.repository.ProcessDefinitionQuery; | |
| 27 | +import org.springframework.stereotype.Service; | |
| 28 | +import org.springframework.validation.annotation.Validated; | |
| 29 | + | |
| 30 | +import javax.annotation.Resource; | |
| 31 | +import javax.validation.Valid; | |
| 32 | +import java.util.*; | |
| 33 | + | |
| 34 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 35 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | |
| 36 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | |
| 37 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH; | |
| 38 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH; | |
| 39 | +import static java.util.Collections.emptyList; | |
| 40 | + | |
| 41 | +/** | |
| 42 | + * 流程定义实现 | |
| 43 | + * 主要进行 Flowable {@link ProcessDefinition} 和 {@link Deployment} 的维护 | |
| 44 | + * | |
| 45 | + * @author yunlongn | |
| 46 | + * @author ZJQ | |
| 47 | + * @author 芋道源码 | |
| 48 | + */ | |
| 49 | +@Service | |
| 50 | +@Validated | |
| 51 | +@Slf4j | |
| 52 | +public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService { | |
| 53 | + | |
| 54 | + private static final String BPMN_FILE_SUFFIX = ".bpmn"; | |
| 55 | + | |
| 56 | + @Resource | |
| 57 | + private RepositoryService repositoryService; | |
| 58 | + | |
| 59 | + @Resource | |
| 60 | + private BpmProcessDefinitionExtMapper processDefinitionMapper; | |
| 61 | + | |
| 62 | + @Resource | |
| 63 | + private BpmFormService formService; | |
| 64 | + | |
| 65 | + @Override | |
| 66 | + public ProcessDefinition getProcessDefinition(String id) { | |
| 67 | + return repositoryService.getProcessDefinition(id); | |
| 68 | + } | |
| 69 | + | |
| 70 | + @Override | |
| 71 | + public ProcessDefinition getProcessDefinition2(String id) { | |
| 72 | + return repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult(); | |
| 73 | + } | |
| 74 | + | |
| 75 | + @Override | |
| 76 | + public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) { | |
| 77 | + if (StrUtil.isEmpty(deploymentId)) { | |
| 78 | + return null; | |
| 79 | + } | |
| 80 | + return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult(); | |
| 81 | + } | |
| 82 | + | |
| 83 | + @Override | |
| 84 | + public List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds) { | |
| 85 | + if (CollUtil.isEmpty(deploymentIds)) { | |
| 86 | + return emptyList(); | |
| 87 | + } | |
| 88 | + return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list(); | |
| 89 | + } | |
| 90 | + | |
| 91 | + @Override | |
| 92 | + public ProcessDefinition getActiveProcessDefinition(String key) { | |
| 93 | + return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active().singleResult(); | |
| 94 | + } | |
| 95 | + | |
| 96 | + @Override | |
| 97 | + public List<Deployment> getDeployments(Set<String> ids) { | |
| 98 | + if (CollUtil.isEmpty(ids)) { | |
| 99 | + return emptyList(); | |
| 100 | + } | |
| 101 | + List<Deployment> list = new ArrayList<>(ids.size()); | |
| 102 | + for (String id : ids) { | |
| 103 | + addIfNotNull(list, getDeployment(id)); | |
| 104 | + } | |
| 105 | + return list; | |
| 106 | + } | |
| 107 | + | |
| 108 | + @Override | |
| 109 | + public Deployment getDeployment(String id) { | |
| 110 | + if (StrUtil.isEmpty(id)) { | |
| 111 | + return null; | |
| 112 | + } | |
| 113 | + return repositoryService.createDeploymentQuery().deploymentId(id).singleResult(); | |
| 114 | + } | |
| 115 | + | |
| 116 | + @Override | |
| 117 | + public BpmnModel getBpmnModel(String processDefinitionId) { | |
| 118 | + return repositoryService.getBpmnModel(processDefinitionId); | |
| 119 | + } | |
| 120 | + | |
| 121 | + @Override | |
| 122 | + public String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) { | |
| 123 | + // 创建 Deployment 部署 | |
| 124 | + Deployment deploy = repositoryService.createDeployment() | |
| 125 | + .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) | |
| 126 | + .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) | |
| 127 | + .deploy(); | |
| 128 | + | |
| 129 | + // 设置 ProcessDefinition 的 category 分类 | |
| 130 | + ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult(); | |
| 131 | + repositoryService.setProcessDefinitionCategory(definition.getId(), createReqDTO.getCategory()); | |
| 132 | + // 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 <bpmn2:process /> 的 id 和 name 决定 | |
| 133 | + // 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。 | |
| 134 | + // 否则,会导致 ProcessDefinition 的分页无法查询到。 | |
| 135 | + if (!Objects.equals(definition.getKey(), createReqDTO.getKey())) { | |
| 136 | + throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, createReqDTO.getKey(), definition.getKey()); | |
| 137 | + } | |
| 138 | + if (!Objects.equals(definition.getName(), createReqDTO.getName())) { | |
| 139 | + throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, createReqDTO.getName(), definition.getName()); | |
| 140 | + } | |
| 141 | + | |
| 142 | + // 插入拓展表 | |
| 143 | + BpmProcessDefinitionExtDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO) | |
| 144 | + .setProcessDefinitionId(definition.getId()); | |
| 145 | + processDefinitionMapper.insert(definitionDO); | |
| 146 | + return definition.getId(); | |
| 147 | + } | |
| 148 | + | |
| 149 | + @Override | |
| 150 | + public void updateProcessDefinitionState(String id, Integer state) { | |
| 151 | + // 激活 | |
| 152 | + if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) { | |
| 153 | + repositoryService.activateProcessDefinitionById(id, false, null); | |
| 154 | + return; | |
| 155 | + } | |
| 156 | + // 挂起 | |
| 157 | + if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) { | |
| 158 | + // suspendProcessInstances = false,进行中的任务,不进行挂起。 | |
| 159 | + // 原因:只要新的流程不允许发起即可,老流程继续可以执行。 | |
| 160 | + repositoryService.suspendProcessDefinitionById(id, false, null); | |
| 161 | + return; | |
| 162 | + } | |
| 163 | + log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state); | |
| 164 | + } | |
| 165 | + | |
| 166 | + @Override | |
| 167 | + public String getProcessDefinitionBpmnXML(String id) { | |
| 168 | + BpmnModel bpmnModel = repositoryService.getBpmnModel(id); | |
| 169 | + if (bpmnModel == null) { | |
| 170 | + return null; | |
| 171 | + } | |
| 172 | + BpmnXMLConverter converter = new BpmnXMLConverter(); | |
| 173 | + return StrUtil.utf8Str(converter.convertToXML(bpmnModel)); | |
| 174 | + } | |
| 175 | + | |
| 176 | + @Override | |
| 177 | + public boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) { | |
| 178 | + // 校验 name、description 是否更新 | |
| 179 | + ProcessDefinition oldProcessDefinition = getActiveProcessDefinition(createReqDTO.getKey()); | |
| 180 | + if (oldProcessDefinition == null) { | |
| 181 | + return false; | |
| 182 | + } | |
| 183 | + BpmProcessDefinitionExtDO oldProcessDefinitionExt = getProcessDefinitionExt(oldProcessDefinition.getId()); | |
| 184 | + if (!StrUtil.equals(createReqDTO.getName(), oldProcessDefinition.getName()) | |
| 185 | + || !StrUtil.equals(createReqDTO.getDescription(), oldProcessDefinitionExt.getDescription()) | |
| 186 | + || !StrUtil.equals(createReqDTO.getCategory(), oldProcessDefinition.getCategory())) { | |
| 187 | + return false; | |
| 188 | + } | |
| 189 | + // 校验 form 信息是否更新 | |
| 190 | + if (!ObjectUtil.equal(createReqDTO.getFormType(), oldProcessDefinitionExt.getFormType()) | |
| 191 | + || !ObjectUtil.equal(createReqDTO.getFormId(), oldProcessDefinitionExt.getFormId()) | |
| 192 | + || !ObjectUtil.equal(createReqDTO.getFormConf(), oldProcessDefinitionExt.getFormConf()) | |
| 193 | + || !ObjectUtil.equal(createReqDTO.getFormFields(), oldProcessDefinitionExt.getFormFields()) | |
| 194 | + || !ObjectUtil.equal(createReqDTO.getFormCustomCreatePath(), oldProcessDefinitionExt.getFormCustomCreatePath()) | |
| 195 | + || !ObjectUtil.equal(createReqDTO.getFormCustomViewPath(), oldProcessDefinitionExt.getFormCustomViewPath())) { | |
| 196 | + return false; | |
| 197 | + } | |
| 198 | + // 校验 BPMN XML 信息 | |
| 199 | + BpmnModel newModel = buildBpmnModel(createReqDTO.getBpmnBytes()); | |
| 200 | + BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId()); | |
| 201 | + //TODO 貌似 flowable 不修改这个也不同。需要看看。 sourceSystemId 不同 | |
| 202 | + if (FlowableUtils.equals(oldModel, newModel)) { | |
| 203 | + return false; | |
| 204 | + } | |
| 205 | + // 最终发现都一致,则返回 true | |
| 206 | + return true; | |
| 207 | + } | |
| 208 | + | |
| 209 | + /** | |
| 210 | + * 构建对应的 BPMN Model | |
| 211 | + * | |
| 212 | + * @param bpmnBytes 原始的 BPMN XML 字节数组 | |
| 213 | + * @return BPMN Model | |
| 214 | + */ | |
| 215 | + private BpmnModel buildBpmnModel(byte[] bpmnBytes) { | |
| 216 | + // 转换成 BpmnModel 对象 | |
| 217 | + BpmnXMLConverter converter = new BpmnXMLConverter(); | |
| 218 | + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true); | |
| 219 | + } | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + @Override | |
| 224 | + public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) { | |
| 225 | + return processDefinitionMapper.selectByProcessDefinitionId(id); | |
| 226 | + } | |
| 227 | + | |
| 228 | + @Override | |
| 229 | + public List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO) { | |
| 230 | + // 拼接查询条件 | |
| 231 | + ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery(); | |
| 232 | + if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), listReqVO.getSuspensionState())) { | |
| 233 | + definitionQuery.suspended(); | |
| 234 | + } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), listReqVO.getSuspensionState())) { | |
| 235 | + definitionQuery.active(); | |
| 236 | + } | |
| 237 | + // 执行查询 | |
| 238 | + List<ProcessDefinition> processDefinitions = definitionQuery.list(); | |
| 239 | + if (CollUtil.isEmpty(processDefinitions)) { | |
| 240 | + return Collections.emptyList(); | |
| 241 | + } | |
| 242 | + | |
| 243 | + // 获得 BpmProcessDefinitionDO Map | |
| 244 | + List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds( | |
| 245 | + convertList(processDefinitions, ProcessDefinition::getId)); | |
| 246 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs, | |
| 247 | + BpmProcessDefinitionExtDO::getProcessDefinitionId); | |
| 248 | + // 执行查询,并返回 | |
| 249 | + return BpmProcessDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap); | |
| 250 | + } | |
| 251 | + | |
| 252 | + @Override | |
| 253 | + public PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) { | |
| 254 | + ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery(); | |
| 255 | + if (StrUtil.isNotBlank(pageVO.getKey())) { | |
| 256 | + definitionQuery.processDefinitionKey(pageVO.getKey()); | |
| 257 | + } | |
| 258 | + | |
| 259 | + // 执行查询 | |
| 260 | + List<ProcessDefinition> processDefinitions = definitionQuery.orderByProcessDefinitionVersion().desc() | |
| 261 | + .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); | |
| 262 | + | |
| 263 | + if (CollUtil.isEmpty(processDefinitions)) { | |
| 264 | + return new PageResult<>(emptyList(), definitionQuery.count()); | |
| 265 | + } | |
| 266 | + // 获得 Deployment Map | |
| 267 | + Set<String> deploymentIds = new HashSet<>(); | |
| 268 | + processDefinitions.forEach(definition -> addIfNotNull(deploymentIds, definition.getDeploymentId())); | |
| 269 | + Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds); | |
| 270 | + | |
| 271 | + // 获得 BpmProcessDefinitionDO Map | |
| 272 | + List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds( | |
| 273 | + convertList(processDefinitions, ProcessDefinition::getId)); | |
| 274 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs, | |
| 275 | + BpmProcessDefinitionExtDO::getProcessDefinitionId); | |
| 276 | + | |
| 277 | + // 获得 Form Map | |
| 278 | + Set<Long> formIds = convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId); | |
| 279 | + Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds); | |
| 280 | + | |
| 281 | + // 拼接结果 | |
| 282 | + long definitionCount = definitionQuery.count(); | |
| 283 | + return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap, | |
| 284 | + processDefinitionDOMap, formMap), definitionCount); | |
| 285 | + } | |
| 286 | + | |
| 287 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; | |
| 7 | +import org.springframework.lang.Nullable; | |
| 8 | + | |
| 9 | +import javax.validation.Valid; | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * BPM 任务分配规则 Service 接口 | |
| 14 | + * | |
| 15 | + * @author 芋道源码 | |
| 16 | + */ | |
| 17 | +public interface BpmTaskAssignRuleService { | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * 获得流程定义的任务分配规则数组 | |
| 21 | + * | |
| 22 | + * @param processDefinitionId 流程定义的编号 | |
| 23 | + * @param taskDefinitionKey 流程任务定义的 Key。允许空 | |
| 24 | + * @return 任务规则数组 | |
| 25 | + */ | |
| 26 | + List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, | |
| 27 | + @Nullable String taskDefinitionKey); | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * 获得流程模型的任务规则数组 | |
| 31 | + * | |
| 32 | + * @param modelId 流程模型的编号 | |
| 33 | + * @return 任务规则数组 | |
| 34 | + */ | |
| 35 | + List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId); | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * 获得流程定义的任务分配规则数组 | |
| 39 | + * | |
| 40 | + * @param modelId 流程模型的编号 | |
| 41 | + * @param processDefinitionId 流程定义的编号 | |
| 42 | + * @return 任务规则数组 | |
| 43 | + */ | |
| 44 | + List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId); | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * 创建任务分配规则 | |
| 48 | + * | |
| 49 | + * @param reqVO 创建信息 | |
| 50 | + * @return 规则编号 | |
| 51 | + */ | |
| 52 | + Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO); | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * 更新任务分配规则 | |
| 56 | + * | |
| 57 | + * @param reqVO 创建信息 | |
| 58 | + */ | |
| 59 | + void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO); | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * 判断指定流程模型和流程定义的分配规则是否相等 | |
| 63 | + * | |
| 64 | + * @param modelId 流程模型编号 | |
| 65 | + * @param processDefinitionId 流程定义编号 | |
| 66 | + * @return 是否相等 | |
| 67 | + */ | |
| 68 | + boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId); | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * 将流程流程模型的任务分配规则,复制一份给流程定义 | |
| 72 | + * 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义 | |
| 73 | + * | |
| 74 | + * @param fromModelId 流程模型编号 | |
| 75 | + * @param toProcessDefinitionId 流程定义编号 | |
| 76 | + */ | |
| 77 | + void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId); | |
| 78 | + | |
| 79 | + /** | |
| 80 | + * 校验流程模型的任务分配规则全部都配置了 | |
| 81 | + * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去! | |
| 82 | + * | |
| 83 | + * @param id 流程模型编号 | |
| 84 | + */ | |
| 85 | + void checkTaskAssignRuleAllConfig(String id); | |
| 86 | + | |
| 87 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.util.ObjectUtil; | |
| 5 | +import cn.hutool.core.util.StrUtil; | |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 7 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | |
| 8 | +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; | |
| 9 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; | |
| 10 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; | |
| 11 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; | |
| 12 | +import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert; | |
| 13 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; | |
| 14 | +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; | |
| 15 | +import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; | |
| 16 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 17 | +import cn.iocoder.yudao.module.system.api.dept.DeptApi; | |
| 18 | +import cn.iocoder.yudao.module.system.api.dept.PostApi; | |
| 19 | +import cn.iocoder.yudao.module.system.api.dict.DictDataApi; | |
| 20 | +import cn.iocoder.yudao.module.system.api.permission.RoleApi; | |
| 21 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 22 | +import lombok.extern.slf4j.Slf4j; | |
| 23 | +import org.flowable.bpmn.model.BpmnModel; | |
| 24 | +import org.flowable.bpmn.model.UserTask; | |
| 25 | +import org.springframework.context.annotation.Lazy; | |
| 26 | +import org.springframework.stereotype.Service; | |
| 27 | +import org.springframework.validation.annotation.Validated; | |
| 28 | + | |
| 29 | +import javax.annotation.Resource; | |
| 30 | +import javax.validation.Valid; | |
| 31 | +import java.util.*; | |
| 32 | + | |
| 33 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 34 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; | |
| 35 | + | |
| 36 | +/** | |
| 37 | + * BPM 任务分配规则 Service 实现类 | |
| 38 | + */ | |
| 39 | +@Service | |
| 40 | +@Validated | |
| 41 | +@Slf4j | |
| 42 | +public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ | |
| 43 | + | |
| 44 | + @Resource | |
| 45 | + private BpmTaskAssignRuleMapper taskRuleMapper; | |
| 46 | + @Resource | |
| 47 | + @Lazy // 解决循环依赖 | |
| 48 | + private BpmModelService modelService; | |
| 49 | + @Resource | |
| 50 | + @Lazy // 解决循环依赖 | |
| 51 | + private BpmProcessDefinitionService processDefinitionService; | |
| 52 | + @Resource | |
| 53 | + private BpmUserGroupService userGroupService; | |
| 54 | + @Resource | |
| 55 | + private RoleApi roleApi; | |
| 56 | + @Resource | |
| 57 | + private DeptApi deptApi; | |
| 58 | + @Resource | |
| 59 | + private PostApi postApi; | |
| 60 | + @Resource | |
| 61 | + private AdminUserApi adminUserApi; | |
| 62 | + @Resource | |
| 63 | + private DictDataApi dictDataApi; | |
| 64 | + | |
| 65 | + @Override | |
| 66 | + public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, String taskDefinitionKey) { | |
| 67 | + return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey); | |
| 68 | + } | |
| 69 | + | |
| 70 | + @Override | |
| 71 | + public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId) { | |
| 72 | + return taskRuleMapper.selectListByModelId(modelId); | |
| 73 | + } | |
| 74 | + | |
| 75 | + @Override | |
| 76 | + public List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId) { | |
| 77 | + // 获得规则 | |
| 78 | + List<BpmTaskAssignRuleDO> rules = Collections.emptyList(); | |
| 79 | + BpmnModel model = null; | |
| 80 | + if (StrUtil.isNotEmpty(modelId)) { | |
| 81 | + rules = getTaskAssignRuleListByModelId(modelId); | |
| 82 | + model = modelService.getBpmnModel(modelId); | |
| 83 | + } else if (StrUtil.isNotEmpty(processDefinitionId)) { | |
| 84 | + rules = getTaskAssignRuleListByProcessDefinitionId(processDefinitionId, null); | |
| 85 | + model = processDefinitionService.getBpmnModel(processDefinitionId); | |
| 86 | + } | |
| 87 | + if (model == null) { | |
| 88 | + return Collections.emptyList(); | |
| 89 | + } | |
| 90 | + // 获得用户任务,只有用户任务才可以设置分配规则 | |
| 91 | + List<UserTask> userTasks = FlowableUtils.getBpmnModelElements(model, UserTask.class); | |
| 92 | + if (CollUtil.isEmpty(userTasks)) { | |
| 93 | + return Collections.emptyList(); | |
| 94 | + } | |
| 95 | + // 转换数据 | |
| 96 | + return BpmTaskAssignRuleConvert.INSTANCE.convertList(userTasks, rules); | |
| 97 | + } | |
| 98 | + | |
| 99 | + @Override | |
| 100 | + public Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO) { | |
| 101 | + // 校验参数 | |
| 102 | + validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions()); | |
| 103 | + // 校验是否已经配置 | |
| 104 | + BpmTaskAssignRuleDO existRule = taskRuleMapper.selectListByModelIdAndTaskDefinitionKey( | |
| 105 | + reqVO.getModelId(), reqVO.getTaskDefinitionKey()); | |
| 106 | + if (existRule != null) { | |
| 107 | + throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey()); | |
| 108 | + } | |
| 109 | + | |
| 110 | + // 存储 | |
| 111 | + BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO) | |
| 112 | + .setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建 | |
| 113 | + taskRuleMapper.insert(rule); | |
| 114 | + return rule.getId(); | |
| 115 | + } | |
| 116 | + | |
| 117 | + @Override | |
| 118 | + public void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO) { | |
| 119 | + // 校验参数 | |
| 120 | + validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions()); | |
| 121 | + // 校验是否存在 | |
| 122 | + BpmTaskAssignRuleDO existRule = taskRuleMapper.selectById(reqVO.getId()); | |
| 123 | + if (existRule == null) { | |
| 124 | + throw exception(TASK_ASSIGN_RULE_NOT_EXISTS); | |
| 125 | + } | |
| 126 | + // 只允许修改流程模型的规则 | |
| 127 | + if (!Objects.equals(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL, existRule.getProcessDefinitionId())) { | |
| 128 | + throw exception(TASK_UPDATE_FAIL_NOT_MODEL); | |
| 129 | + } | |
| 130 | + | |
| 131 | + // 执行更新 | |
| 132 | + taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)); | |
| 133 | + } | |
| 134 | + | |
| 135 | + @Override | |
| 136 | + public boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId) { | |
| 137 | + // 调用 VO 接口的原因是,过滤掉流程模型不需要的规则,保持和 copyTaskAssignRules 方法的一致性 | |
| 138 | + List<BpmTaskAssignRuleRespVO> modelRules = getTaskAssignRuleList(modelId, null); | |
| 139 | + List<BpmTaskAssignRuleRespVO> processInstanceRules = getTaskAssignRuleList(null, processDefinitionId); | |
| 140 | + if (modelRules.size() != processInstanceRules.size()) { | |
| 141 | + return false; | |
| 142 | + } | |
| 143 | + | |
| 144 | + // 遍历,匹配对应的规则 | |
| 145 | + Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap = CollectionUtils.convertMap(processInstanceRules, | |
| 146 | + BpmTaskAssignRuleRespVO::getTaskDefinitionKey); | |
| 147 | + for (BpmTaskAssignRuleRespVO modelRule : modelRules) { | |
| 148 | + BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey()); | |
| 149 | + if (processInstanceRule == null) { | |
| 150 | + return false; | |
| 151 | + } | |
| 152 | + if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType()) | |
| 153 | + || !ObjectUtil.equal(modelRule.getOptions(), processInstanceRule.getOptions())) { | |
| 154 | + return false; | |
| 155 | + } | |
| 156 | + } | |
| 157 | + return true; | |
| 158 | + } | |
| 159 | + | |
| 160 | + @Override | |
| 161 | + public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) { | |
| 162 | + List<BpmTaskAssignRuleRespVO> rules = getTaskAssignRuleList(fromModelId, null); | |
| 163 | + if (CollUtil.isEmpty(rules)) { | |
| 164 | + return; | |
| 165 | + } | |
| 166 | + // 开始复制 | |
| 167 | + List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules); | |
| 168 | + newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null) | |
| 169 | + .setCreateTime(null).setUpdateTime(null)); | |
| 170 | + taskRuleMapper.insertBatch(newRules); | |
| 171 | + } | |
| 172 | + | |
| 173 | + @Override | |
| 174 | + public void checkTaskAssignRuleAllConfig(String id) { | |
| 175 | + // 一个用户任务都没配置,所以无需配置规则 | |
| 176 | + List<BpmTaskAssignRuleRespVO> taskAssignRules = getTaskAssignRuleList(id, null); | |
| 177 | + if (CollUtil.isEmpty(taskAssignRules)) { | |
| 178 | + return; | |
| 179 | + } | |
| 180 | + // 校验未配置规则的任务 | |
| 181 | + taskAssignRules.forEach(rule -> { | |
| 182 | + if (CollUtil.isEmpty(rule.getOptions())) { | |
| 183 | + throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName()); | |
| 184 | + } | |
| 185 | + }); | |
| 186 | + } | |
| 187 | + | |
| 188 | + private void validTaskAssignRuleOptions(Integer type, Set<Long> options) { | |
| 189 | + if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) { | |
| 190 | + roleApi.validRoles(options); | |
| 191 | + } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), | |
| 192 | + BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) { | |
| 193 | + deptApi.validDepts(options); | |
| 194 | + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) { | |
| 195 | + postApi.validPosts(options); | |
| 196 | + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER.getType())) { | |
| 197 | + adminUserApi.validUsers(options); | |
| 198 | + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) { | |
| 199 | + userGroupService.validUserGroups(options); | |
| 200 | + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) { | |
| 201 | + dictDataApi.validDictDatas(DictTypeConstants.TASK_ASSIGN_SCRIPT, | |
| 202 | + CollectionUtils.convertSet(options, String::valueOf)); | |
| 203 | + } else { | |
| 204 | + throw new IllegalArgumentException(StrUtil.format("未知的规则类型({})", type)); | |
| 205 | + } | |
| 206 | + } | |
| 207 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import java.util.*; | |
| 4 | +import javax.validation.*; | |
| 5 | + | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | |
| 10 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * 用户组 Service 接口 | |
| 14 | + * | |
| 15 | + * @author 芋道源码 | |
| 16 | + */ | |
| 17 | +public interface BpmUserGroupService { | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * 创建用户组 | |
| 21 | + * | |
| 22 | + * @param createReqVO 创建信息 | |
| 23 | + * @return 编号 | |
| 24 | + */ | |
| 25 | + Long createUserGroup(@Valid BpmUserGroupCreateReqVO createReqVO); | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * 更新用户组 | |
| 29 | + * | |
| 30 | + * @param updateReqVO 更新信息 | |
| 31 | + */ | |
| 32 | + void updateUserGroup(@Valid BpmUserGroupUpdateReqVO updateReqVO); | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * 删除用户组 | |
| 36 | + * | |
| 37 | + * @param id 编号 | |
| 38 | + */ | |
| 39 | + void deleteUserGroup(Long id); | |
| 40 | + | |
| 41 | + /** | |
| 42 | + * 获得用户组 | |
| 43 | + * | |
| 44 | + * @param id 编号 | |
| 45 | + * @return 用户组 | |
| 46 | + */ | |
| 47 | + BpmUserGroupDO getUserGroup(Long id); | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * 获得用户组列表 | |
| 51 | + * | |
| 52 | + * @param ids 编号 | |
| 53 | + * @return 用户组列表 | |
| 54 | + */ | |
| 55 | + List<BpmUserGroupDO> getUserGroupList(Collection<Long> ids); | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * 获得指定状态的用户组列表 | |
| 59 | + * | |
| 60 | + * @param status 状态 | |
| 61 | + * @return 用户组列表 | |
| 62 | + */ | |
| 63 | + List<BpmUserGroupDO> getUserGroupListByStatus(Integer status); | |
| 64 | + | |
| 65 | + /** | |
| 66 | + * 获得用户组分页 | |
| 67 | + * | |
| 68 | + * @param pageReqVO 分页查询 | |
| 69 | + * @return 用户组分页 | |
| 70 | + */ | |
| 71 | + PageResult<BpmUserGroupDO> getUserGroupPage(BpmUserGroupPageReqVO pageReqVO); | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * 校验用户组们是否有效。如下情况,视为无效: | |
| 75 | + * 1. 用户组编号不存在 | |
| 76 | + * 2. 用户组被禁用 | |
| 77 | + * | |
| 78 | + * @param ids 用户组编号数组 | |
| 79 | + */ | |
| 80 | + void validUserGroups(Set<Long> ids); | |
| 81 | + | |
| 82 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.convert.definition.BpmUserGroupConvert; | |
| 8 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmUserGroupMapper; | |
| 10 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 11 | +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | |
| 12 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 13 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 14 | +import org.springframework.stereotype.Service; | |
| 15 | +import org.springframework.validation.annotation.Validated; | |
| 16 | + | |
| 17 | +import javax.annotation.Resource; | |
| 18 | +import java.util.Collection; | |
| 19 | +import java.util.List; | |
| 20 | +import java.util.Map; | |
| 21 | +import java.util.Set; | |
| 22 | + | |
| 23 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 24 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; | |
| 25 | + | |
| 26 | +/** | |
| 27 | + * 用户组 Service 实现类 | |
| 28 | + * | |
| 29 | + * @author 芋道源码 | |
| 30 | + */ | |
| 31 | +@Service | |
| 32 | +@Validated | |
| 33 | +public class BpmUserGroupServiceImpl implements BpmUserGroupService { | |
| 34 | + | |
| 35 | + @Resource | |
| 36 | + private BpmUserGroupMapper userGroupMapper; | |
| 37 | + | |
| 38 | + @Override | |
| 39 | + public Long createUserGroup(BpmUserGroupCreateReqVO createReqVO) { | |
| 40 | + // 插入 | |
| 41 | + BpmUserGroupDO userGroup = BpmUserGroupConvert.INSTANCE.convert(createReqVO); | |
| 42 | + userGroupMapper.insert(userGroup); | |
| 43 | + // 返回 | |
| 44 | + return userGroup.getId(); | |
| 45 | + } | |
| 46 | + | |
| 47 | + @Override | |
| 48 | + public void updateUserGroup(BpmUserGroupUpdateReqVO updateReqVO) { | |
| 49 | + // 校验存在 | |
| 50 | + this.validateUserGroupExists(updateReqVO.getId()); | |
| 51 | + // 更新 | |
| 52 | + BpmUserGroupDO updateObj = BpmUserGroupConvert.INSTANCE.convert(updateReqVO); | |
| 53 | + userGroupMapper.updateById(updateObj); | |
| 54 | + } | |
| 55 | + | |
| 56 | + @Override | |
| 57 | + public void deleteUserGroup(Long id) { | |
| 58 | + // 校验存在 | |
| 59 | + this.validateUserGroupExists(id); | |
| 60 | + // 删除 | |
| 61 | + userGroupMapper.deleteById(id); | |
| 62 | + } | |
| 63 | + | |
| 64 | + private void validateUserGroupExists(Long id) { | |
| 65 | + if (userGroupMapper.selectById(id) == null) { | |
| 66 | + throw ServiceExceptionUtil.exception(USER_GROUP_NOT_EXISTS); | |
| 67 | + } | |
| 68 | + } | |
| 69 | + | |
| 70 | + @Override | |
| 71 | + public BpmUserGroupDO getUserGroup(Long id) { | |
| 72 | + return userGroupMapper.selectById(id); | |
| 73 | + } | |
| 74 | + | |
| 75 | + @Override | |
| 76 | + public List<BpmUserGroupDO> getUserGroupList(Collection<Long> ids) { | |
| 77 | + return userGroupMapper.selectBatchIds(ids); | |
| 78 | + } | |
| 79 | + | |
| 80 | + | |
| 81 | + @Override | |
| 82 | + public List<BpmUserGroupDO> getUserGroupListByStatus(Integer status) { | |
| 83 | + return userGroupMapper.selectListByStatus(status); | |
| 84 | + } | |
| 85 | + | |
| 86 | + @Override | |
| 87 | + public PageResult<BpmUserGroupDO> getUserGroupPage(BpmUserGroupPageReqVO pageReqVO) { | |
| 88 | + return userGroupMapper.selectPage(pageReqVO); | |
| 89 | + } | |
| 90 | + | |
| 91 | + @Override | |
| 92 | + public void validUserGroups(Set<Long> ids) { | |
| 93 | + if (CollUtil.isEmpty(ids)) { | |
| 94 | + return; | |
| 95 | + } | |
| 96 | + // 获得用户组信息 | |
| 97 | + List<BpmUserGroupDO> userGroups = userGroupMapper.selectBatchIds(ids); | |
| 98 | + Map<Long, BpmUserGroupDO> userGroupMap = CollectionUtils.convertMap(userGroups, BpmUserGroupDO::getId); | |
| 99 | + // 校验 | |
| 100 | + ids.forEach(id -> { | |
| 101 | + BpmUserGroupDO userGroup = userGroupMap.get(id); | |
| 102 | + if (userGroup == null) { | |
| 103 | + throw ServiceExceptionUtil.exception(USER_GROUP_NOT_EXISTS); | |
| 104 | + } | |
| 105 | + if (!CommonStatusEnum.ENABLE.getStatus().equals(userGroup.getStatus())) { | |
| 106 | + throw exception(USER_GROUP_IS_DISABLE, userGroup.getName()); | |
| 107 | + } | |
| 108 | + }); | |
| 109 | + } | |
| 110 | + | |
| 111 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmFormFieldRespDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition.dto; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.JsonProperty; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * Bpm 表单的 Field 表单项 Response DTO | |
| 8 | + * 字段的定义,可见 https://github.com/JakHuang/form-generator/issues/46 文档 | |
| 9 | + * | |
| 10 | + * @author 芋道源码 | |
| 11 | + */ | |
| 12 | +@Data | |
| 13 | +public class BpmFormFieldRespDTO { | |
| 14 | + | |
| 15 | + /** | |
| 16 | + * 表单标题 | |
| 17 | + */ | |
| 18 | + private String label; | |
| 19 | + /** | |
| 20 | + * 表单字段的属性名,可自定义 | |
| 21 | + */ | |
| 22 | + @JsonProperty(value = "vModel") | |
| 23 | + private String vModel; | |
| 24 | + | |
| 25 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition.dto; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * BPM 流程 MetaInfo Response DTO | |
| 8 | + * 主要用于 { Model#setMetaInfo(String)} 的存储 | |
| 9 | + * | |
| 10 | + * @author 芋道源码 | |
| 11 | + */ | |
| 12 | +@Data | |
| 13 | +public class BpmModelMetaInfoRespDTO { | |
| 14 | + | |
| 15 | + /** | |
| 16 | + * 流程描述 | |
| 17 | + */ | |
| 18 | + private String description; | |
| 19 | + /** | |
| 20 | + * 表单类型 | |
| 21 | + */ | |
| 22 | + private Integer formType; | |
| 23 | + /** | |
| 24 | + * 表单编号 | |
| 25 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 26 | + */ | |
| 27 | + private Long formId; | |
| 28 | + /** | |
| 29 | + * 自定义表单的提交路径,使用 Vue 的路由地址 | |
| 30 | + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 | |
| 31 | + */ | |
| 32 | + private String formCustomCreatePath; | |
| 33 | + /** | |
| 34 | + * 自定义表单的查看路径,使用 Vue 的路由地址 | |
| 35 | + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 | |
| 36 | + */ | |
| 37 | + private String formCustomViewPath; | |
| 38 | + | |
| 39 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition.dto; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; | |
| 6 | +import lombok.Data; | |
| 7 | + | |
| 8 | +import javax.validation.constraints.AssertTrue; | |
| 9 | +import javax.validation.constraints.NotEmpty; | |
| 10 | +import javax.validation.constraints.NotNull; | |
| 11 | +import java.util.List; | |
| 12 | +import java.util.Objects; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * 流程定义创建 Request DTO | |
| 16 | + */ | |
| 17 | +@Data | |
| 18 | +public class BpmProcessDefinitionCreateReqDTO { | |
| 19 | + | |
| 20 | + // ========== 模型相关 ========== | |
| 21 | + | |
| 22 | + /** | |
| 23 | + * 流程模型的编号 | |
| 24 | + */ | |
| 25 | + @NotEmpty(message = "流程模型编号不能为空") | |
| 26 | + private String modelId; | |
| 27 | + /** | |
| 28 | + * 流程标识 | |
| 29 | + */ | |
| 30 | + @NotEmpty(message = "流程标识不能为空") | |
| 31 | + private String key; | |
| 32 | + /** | |
| 33 | + * 流程名称 | |
| 34 | + */ | |
| 35 | + @NotEmpty(message = "流程名称不能为空") | |
| 36 | + private String name; | |
| 37 | + /** | |
| 38 | + * 流程描述 | |
| 39 | + */ | |
| 40 | + private String description; | |
| 41 | + /** | |
| 42 | + * 流程分类 | |
| 43 | + * 参见 bpm_model_category 数据字典 | |
| 44 | + */ | |
| 45 | + @NotEmpty(message = "流程分类不能为空") | |
| 46 | + private String category; | |
| 47 | + /** | |
| 48 | + * BPMN XML | |
| 49 | + */ | |
| 50 | + @NotEmpty(message = "BPMN XML 不能为空") | |
| 51 | + private byte[] bpmnBytes; | |
| 52 | + | |
| 53 | + // ========== 表单相关 ========== | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * 表单类型 | |
| 57 | + */ | |
| 58 | + @NotNull(message = "表单类型不能为空") | |
| 59 | + private Integer formType; | |
| 60 | + /** | |
| 61 | + * 动态表单编号 | |
| 62 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 63 | + */ | |
| 64 | + private Long formId; | |
| 65 | + /** | |
| 66 | + * 表单的配置 | |
| 67 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 68 | + */ | |
| 69 | + private String formConf; | |
| 70 | + /** | |
| 71 | + * 表单项的数组 | |
| 72 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 73 | + */ | |
| 74 | + private List<String> formFields; | |
| 75 | + /** | |
| 76 | + * 自定义表单的提交路径,使用 Vue 的路由地址 | |
| 77 | + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 | |
| 78 | + */ | |
| 79 | + private String formCustomCreatePath; | |
| 80 | + /** | |
| 81 | + * 自定义表单的查看路径,使用 Vue 的路由地址 | |
| 82 | + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 | |
| 83 | + */ | |
| 84 | + private String formCustomViewPath; | |
| 85 | + | |
| 86 | + @AssertTrue(message = "流程表单信息不全") | |
| 87 | + public boolean isNormalFormTypeValid() { | |
| 88 | + // 如果非业务表单,则直接通过 | |
| 89 | + if (!Objects.equals(formType, BpmModelFormTypeEnum.NORMAL.getType())) { | |
| 90 | + return true; | |
| 91 | + } | |
| 92 | + return formId != null && StrUtil.isNotEmpty(formConf) && CollUtil.isNotEmpty(formFields); | |
| 93 | + } | |
| 94 | + | |
| 95 | + @AssertTrue(message = "业务表单信息不全") | |
| 96 | + public boolean isNormalCustomTypeValid() { | |
| 97 | + // 如果非业务表单,则直接通过 | |
| 98 | + if (!Objects.equals(formType, BpmModelFormTypeEnum.CUSTOM.getType())) { | |
| 99 | + return true; | |
| 100 | + } | |
| 101 | + return StrUtil.isNotEmpty(formCustomCreatePath) && StrUtil.isNotEmpty(formCustomViewPath); | |
| 102 | + } | |
| 103 | + | |
| 104 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.message; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; | |
| 6 | + | |
| 7 | +import javax.validation.Valid; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * BPM 消息 Service 接口 | |
| 11 | + * | |
| 12 | + * TODO 芋艿:未来支持消息的可配置;不同的流程,在什么场景下,需要发送什么消息,消息的内容是什么; | |
| 13 | + * | |
| 14 | + * @author 芋道源码 | |
| 15 | + */ | |
| 16 | +public interface BpmMessageService { | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * 发送流程实例被通过的消息 | |
| 20 | + * | |
| 21 | + * @param reqDTO 发送信息 | |
| 22 | + */ | |
| 23 | + void sendMessageWhenProcessInstanceApprove(@Valid BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO); | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * 发送流程实例被不通过的消息 | |
| 27 | + * | |
| 28 | + * @param reqDTO 发送信息 | |
| 29 | + */ | |
| 30 | + void sendMessageWhenProcessInstanceReject(@Valid BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO); | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * 发送任务被分配的消息 | |
| 34 | + * | |
| 35 | + * @param reqDTO 发送信息 | |
| 36 | + */ | |
| 37 | + void sendMessageWhenTaskAssigned(@Valid BpmMessageSendWhenTaskCreatedReqDTO reqDTO); | |
| 38 | + | |
| 39 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.message; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.web.config.WebProperties; | |
| 4 | +import cn.iocoder.yudao.module.bpm.convert.message.BpmMessageConvert; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.message.BpmMessageEnum; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; | |
| 9 | +import cn.iocoder.yudao.module.system.api.sms.SmsSendApi; | |
| 10 | +import lombok.extern.slf4j.Slf4j; | |
| 11 | +import org.springframework.stereotype.Service; | |
| 12 | +import org.springframework.validation.annotation.Validated; | |
| 13 | + | |
| 14 | +import javax.annotation.Resource; | |
| 15 | +import java.util.HashMap; | |
| 16 | +import java.util.Map; | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * BPM 消息 Service 实现类 | |
| 20 | + * | |
| 21 | + * @author 芋道源码 | |
| 22 | + */ | |
| 23 | +@Service | |
| 24 | +@Validated | |
| 25 | +@Slf4j | |
| 26 | +public class BpmMessageServiceImpl implements BpmMessageService { | |
| 27 | + | |
| 28 | + @Resource | |
| 29 | + private SmsSendApi smsSendApi; | |
| 30 | + | |
| 31 | + @Resource | |
| 32 | + private WebProperties webProperties; | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + public void sendMessageWhenProcessInstanceApprove(BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO) { | |
| 36 | + Map<String, Object> templateParams = new HashMap<>(); | |
| 37 | + templateParams.put("processInstanceName", reqDTO.getProcessInstanceName()); | |
| 38 | + templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId())); | |
| 39 | + smsSendApi.sendSingleSmsToAdmin(BpmMessageConvert.INSTANCE.convert(reqDTO.getStartUserId(), | |
| 40 | + BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getSmsTemplateCode(), templateParams)); | |
| 41 | + } | |
| 42 | + | |
| 43 | + @Override | |
| 44 | + public void sendMessageWhenProcessInstanceReject(BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO) { | |
| 45 | + Map<String, Object> templateParams = new HashMap<>(); | |
| 46 | + templateParams.put("processInstanceName", reqDTO.getProcessInstanceName()); | |
| 47 | + templateParams.put("comment", reqDTO.getComment()); | |
| 48 | + templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId())); | |
| 49 | + smsSendApi.sendSingleSmsToAdmin(BpmMessageConvert.INSTANCE.convert(reqDTO.getStartUserId(), | |
| 50 | + BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsTemplateCode(), templateParams)); | |
| 51 | + } | |
| 52 | + | |
| 53 | + @Override | |
| 54 | + public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) { | |
| 55 | + Map<String, Object> templateParams = new HashMap<>(); | |
| 56 | + templateParams.put("processInstanceName", reqDTO.getProcessInstanceName()); | |
| 57 | + templateParams.put("taskName", reqDTO.getTaskName()); | |
| 58 | + templateParams.put("startUserNickname", reqDTO.getStartUserNickname()); | |
| 59 | + templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId())); | |
| 60 | + smsSendApi.sendSingleSmsToAdmin(BpmMessageConvert.INSTANCE.convert(reqDTO.getStartUserId(), | |
| 61 | + BpmMessageEnum.TASK_ASSIGNED.getSmsTemplateCode(), templateParams)); | |
| 62 | + } | |
| 63 | + | |
| 64 | + private String getProcessInstanceDetailUrl(String taskId) { | |
| 65 | + return webProperties.getAdminUi().getUrl() + "/bpm/process-instance/detail?id=" + taskId; | |
| 66 | + } | |
| 67 | + | |
| 68 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceApproveReqDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.message.dto; | |
| 2 | + | |
| 3 | +import lombok.Data; | |
| 4 | + | |
| 5 | +import javax.validation.constraints.NotEmpty; | |
| 6 | +import javax.validation.constraints.NotNull; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * BPM 发送流程实例被通过 Request DTO | |
| 10 | + */ | |
| 11 | +@Data | |
| 12 | +public class BpmMessageSendWhenProcessInstanceApproveReqDTO { | |
| 13 | + | |
| 14 | + /** | |
| 15 | + * 流程实例的编号 | |
| 16 | + */ | |
| 17 | + @NotEmpty(message = "流程实例的编号不能为空") | |
| 18 | + private String processInstanceId; | |
| 19 | + /** | |
| 20 | + * 流程实例的名字 | |
| 21 | + */ | |
| 22 | + @NotEmpty(message = "流程实例的名字不能为空") | |
| 23 | + private String processInstanceName; | |
| 24 | + @NotNull(message = "发起人的用户编号") | |
| 25 | + private Long startUserId; | |
| 26 | + | |
| 27 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceRejectReqDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.message.dto; | |
| 2 | + | |
| 3 | +import lombok.Data; | |
| 4 | + | |
| 5 | +import javax.validation.constraints.NotEmpty; | |
| 6 | +import javax.validation.constraints.NotNull; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * BPM 发送流程实例被不通过 Request DTO | |
| 10 | + */ | |
| 11 | +@Data | |
| 12 | +public class BpmMessageSendWhenProcessInstanceRejectReqDTO { | |
| 13 | + | |
| 14 | + /** | |
| 15 | + * 流程实例的编号 | |
| 16 | + */ | |
| 17 | + @NotEmpty(message = "流程实例的编号不能为空") | |
| 18 | + private String processInstanceId; | |
| 19 | + /** | |
| 20 | + * 流程实例的名字 | |
| 21 | + */ | |
| 22 | + @NotEmpty(message = "流程实例的名字不能为空") | |
| 23 | + private String processInstanceName; | |
| 24 | + @NotNull(message = "发起人的用户编号") | |
| 25 | + private Long startUserId; | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * 不通过理由 | |
| 29 | + */ | |
| 30 | + @NotEmpty(message = "不通过理由不能为空") | |
| 31 | + private String comment; | |
| 32 | + | |
| 33 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenTaskCreatedReqDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.message.dto; | |
| 2 | + | |
| 3 | +import lombok.Data; | |
| 4 | + | |
| 5 | +import javax.validation.constraints.NotEmpty; | |
| 6 | +import javax.validation.constraints.NotNull; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * BPM 发送任务被分配 Request DTO | |
| 10 | + */ | |
| 11 | +@Data | |
| 12 | +public class BpmMessageSendWhenTaskCreatedReqDTO { | |
| 13 | + | |
| 14 | + /** | |
| 15 | + * 流程实例的编号 | |
| 16 | + */ | |
| 17 | + @NotEmpty(message = "流程实例的编号不能为空") | |
| 18 | + private String processInstanceId; | |
| 19 | + /** | |
| 20 | + * 流程实例的名字 | |
| 21 | + */ | |
| 22 | + @NotEmpty(message = "流程实例的名字不能为空") | |
| 23 | + private String processInstanceName; | |
| 24 | + @NotNull(message = "发起人的用户编号") | |
| 25 | + private Long startUserId; | |
| 26 | + @NotEmpty(message = "发起人的昵称") | |
| 27 | + private String startUserNickname; | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * 流程任务的编号 | |
| 31 | + */ | |
| 32 | + @NotEmpty(message = "流程任务的编号不能为空") | |
| 33 | + private String taskId; | |
| 34 | + /** | |
| 35 | + * 流程任务的名字 | |
| 36 | + */ | |
| 37 | + @NotEmpty(message = "流程任务的名字不能为空") | |
| 38 | + private String taskName; | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * 审批人的用户编号 | |
| 42 | + */ | |
| 43 | + @NotNull(message = "审批人的用户编号不能为空") | |
| 44 | + private Long assigneeUserId; | |
| 45 | + | |
| 46 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.oa; | |
| 2 | + | |
| 3 | + | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveCreateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeavePageReqVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO; | |
| 8 | + | |
| 9 | +import javax.validation.Valid; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * 请假申请 Service 接口 | |
| 13 | + * | |
| 14 | + * @author jason | |
| 15 | + * @author 芋道源码 | |
| 16 | + */ | |
| 17 | +public interface BpmOALeaveService { | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * 创建请假申请 | |
| 21 | + * | |
| 22 | + * @param userId 用户编号 | |
| 23 | + * @param createReqVO 创建信息 | |
| 24 | + * @return 编号 | |
| 25 | + */ | |
| 26 | + Long createLeave(Long userId, @Valid BpmOALeaveCreateReqVO createReqVO); | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 更新请假申请的状态 | |
| 30 | + * | |
| 31 | + * @param id 编号 | |
| 32 | + * @param result 结果 | |
| 33 | + */ | |
| 34 | + void updateLeaveResult(Long id, Integer result); | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * 获得请假申请 | |
| 38 | + * | |
| 39 | + * @param id 编号 | |
| 40 | + * @return 请假申请 | |
| 41 | + */ | |
| 42 | + BpmOALeaveDO getLeave(Long id); | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * 获得请假申请分页 | |
| 46 | + * | |
| 47 | + * @param userId 用户编号 | |
| 48 | + * @param pageReqVO 分页查询 | |
| 49 | + * @return 请假申请分页 | |
| 50 | + */ | |
| 51 | + PageResult<BpmOALeaveDO> getLeavePage(Long userId, BpmOALeavePageReqVO pageReqVO); | |
| 52 | + | |
| 53 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.oa; | |
| 2 | + | |
| 3 | +import cn.hutool.core.date.DateUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; | |
| 6 | +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveCreateReqVO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeavePageReqVO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.convert.oa.BpmOALeaveConvert; | |
| 10 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO; | |
| 11 | +import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOALeaveMapper; | |
| 12 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 13 | +import org.springframework.stereotype.Service; | |
| 14 | +import org.springframework.transaction.annotation.Transactional; | |
| 15 | +import org.springframework.validation.annotation.Validated; | |
| 16 | + | |
| 17 | +import javax.annotation.Resource; | |
| 18 | +import java.util.HashMap; | |
| 19 | +import java.util.Map; | |
| 20 | + | |
| 21 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 22 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_LEAVE_NOT_EXISTS; | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * OA 请假申请 Service 实现类 | |
| 26 | + * | |
| 27 | + * @author jason | |
| 28 | + * @author 芋道源码 | |
| 29 | + */ | |
| 30 | +@Service | |
| 31 | +@Validated | |
| 32 | +public class BpmOALeaveServiceImpl implements BpmOALeaveService { | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * OA 请假对应的流程定义 KEY | |
| 36 | + */ | |
| 37 | + public static final String PROCESS_KEY = "oa_leave"; | |
| 38 | + | |
| 39 | + @Resource | |
| 40 | + private BpmOALeaveMapper leaveMapper; | |
| 41 | + | |
| 42 | + @Resource | |
| 43 | + private BpmProcessInstanceApi processInstanceApi; | |
| 44 | + | |
| 45 | + @Override | |
| 46 | + @Transactional(rollbackFor = Exception.class) | |
| 47 | + public Long createLeave(Long userId, BpmOALeaveCreateReqVO createReqVO) { | |
| 48 | + // 插入 OA 请假单 | |
| 49 | + long day = DateUtil.betweenDay(createReqVO.getStartTime(), createReqVO.getEndTime(), false); | |
| 50 | + BpmOALeaveDO leave = BpmOALeaveConvert.INSTANCE.convert(createReqVO).setUserId(userId).setDay(day) | |
| 51 | + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); | |
| 52 | + leaveMapper.insert(leave); | |
| 53 | + | |
| 54 | + // 发起 BPM 流程 | |
| 55 | + Map<String, Object> processInstanceVariables = new HashMap<>(); | |
| 56 | + processInstanceVariables.put("day", day); | |
| 57 | + String processInstanceId = processInstanceApi.createProcessInstance(userId, | |
| 58 | + new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY) | |
| 59 | + .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(leave.getId()))); | |
| 60 | + | |
| 61 | + // 将工作流的编号,更新到 OA 请假单中 | |
| 62 | + leaveMapper.updateById(new BpmOALeaveDO().setId(leave.getId()).setProcessInstanceId(processInstanceId)); | |
| 63 | + return leave.getId(); | |
| 64 | + } | |
| 65 | + | |
| 66 | + @Override | |
| 67 | + public void updateLeaveResult(Long id, Integer result) { | |
| 68 | + validateLeaveExists(id); | |
| 69 | + leaveMapper.updateById(new BpmOALeaveDO().setId(id).setResult(result)); | |
| 70 | + } | |
| 71 | + | |
| 72 | + private void validateLeaveExists(Long id) { | |
| 73 | + if (leaveMapper.selectById(id) == null) { | |
| 74 | + throw exception(OA_LEAVE_NOT_EXISTS); | |
| 75 | + } | |
| 76 | + } | |
| 77 | + | |
| 78 | + @Override | |
| 79 | + public BpmOALeaveDO getLeave(Long id) { | |
| 80 | + return leaveMapper.selectById(id); | |
| 81 | + } | |
| 82 | + | |
| 83 | + @Override | |
| 84 | + public PageResult<BpmOALeaveDO> getLeavePage(Long userId, BpmOALeavePageReqVO pageReqVO) { | |
| 85 | + return leaveMapper.selectPage(userId, pageReqVO); | |
| 86 | + } | |
| 87 | + | |
| 88 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOALeaveResultListener.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.oa.listener; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent; | |
| 4 | +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventListener; | |
| 5 | +import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveServiceImpl; | |
| 7 | +import org.springframework.stereotype.Component; | |
| 8 | + | |
| 9 | +import javax.annotation.Resource; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * OA 请假单的结果的监听器实现类 | |
| 13 | + * | |
| 14 | + * @author 芋道源码 | |
| 15 | + */ | |
| 16 | +@Component | |
| 17 | +public class BpmOALeaveResultListener extends BpmProcessInstanceResultEventListener { | |
| 18 | + | |
| 19 | + @Resource | |
| 20 | + private BpmOALeaveService leaveService; | |
| 21 | + | |
| 22 | + @Override | |
| 23 | + protected String getProcessDefinitionKey() { | |
| 24 | + return BpmOALeaveServiceImpl.PROCESS_KEY; | |
| 25 | + } | |
| 26 | + | |
| 27 | + @Override | |
| 28 | + protected void onEvent(BpmProcessInstanceResultEvent event) { | |
| 29 | + leaveService.updateLeaveResult(Long.parseLong(event.getBusinessKey()), event.getResult()); | |
| 30 | + } | |
| 31 | + | |
| 32 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; | |
| 4 | + | |
| 5 | +import java.util.List; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * BPM 活动实例 Service 接口 | |
| 9 | + * | |
| 10 | + * @author 芋道源码 | |
| 11 | + */ | |
| 12 | +public interface BpmActivityService { | |
| 13 | + | |
| 14 | + /** | |
| 15 | + * 获得指定流程实例的活动实例列表 | |
| 16 | + * | |
| 17 | + * @param processInstanceId 流程实例的编号 | |
| 18 | + * @return 活动实例列表 | |
| 19 | + */ | |
| 20 | + List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId); | |
| 21 | + | |
| 22 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task; | |
| 2 | + | |
| 3 | +import cn.hutool.core.io.IoUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.convert.task.BpmActivityConvert; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; | |
| 8 | +import lombok.extern.slf4j.Slf4j; | |
| 9 | + | |
| 10 | +import org.flowable.bpmn.model.BpmnModel; | |
| 11 | +import org.flowable.engine.HistoryService; | |
| 12 | +import org.flowable.engine.history.HistoricActivityInstance; | |
| 13 | +import org.flowable.engine.history.HistoricProcessInstance; | |
| 14 | +import org.flowable.image.ProcessDiagramGenerator; | |
| 15 | +import org.springframework.stereotype.Service; | |
| 16 | +import org.springframework.validation.annotation.Validated; | |
| 17 | + | |
| 18 | +import javax.annotation.Resource; | |
| 19 | +import java.io.InputStream; | |
| 20 | +import java.util.Collections; | |
| 21 | +import java.util.List; | |
| 22 | + | |
| 23 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 24 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS; | |
| 25 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS; | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * BPM 活动实例 Service 实现类 | |
| 29 | + * | |
| 30 | + * @author 芋道源码 | |
| 31 | + */ | |
| 32 | +@Service | |
| 33 | +@Slf4j | |
| 34 | +@Validated | |
| 35 | +public class BpmActivityServiceImpl implements BpmActivityService { | |
| 36 | + | |
| 37 | + @Resource | |
| 38 | + private HistoryService historyService; | |
| 39 | + | |
| 40 | + @Override | |
| 41 | + public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) { | |
| 42 | + List<HistoricActivityInstance> activityList = historyService.createHistoricActivityInstanceQuery() | |
| 43 | + .processInstanceId(processInstanceId).list(); | |
| 44 | + return BpmActivityConvert.INSTANCE.convertList(activityList); | |
| 45 | + } | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 5 | +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; | |
| 7 | +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; | |
| 8 | +import org.flowable.engine.delegate.event.FlowableCancelledEvent; | |
| 9 | +import org.flowable.engine.history.HistoricProcessInstance; | |
| 10 | +import org.flowable.engine.runtime.ProcessInstance; | |
| 11 | + | |
| 12 | +import javax.validation.Valid; | |
| 13 | +import java.util.List; | |
| 14 | +import java.util.Map; | |
| 15 | +import java.util.Set; | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * 流程实例 Service 接口 | |
| 19 | + * | |
| 20 | + * @author 芋道源码 | |
| 21 | + */ | |
| 22 | +public interface BpmProcessInstanceService { | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * 获得流程实例 | |
| 26 | + * | |
| 27 | + * @param id 流程实例的编号 | |
| 28 | + * @return 流程实例 | |
| 29 | + */ | |
| 30 | + ProcessInstance getProcessInstance(String id); | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * 获得流程实例列表 | |
| 34 | + * | |
| 35 | + * @param ids 流程实例的编号集合 | |
| 36 | + * @return 流程实例列表 | |
| 37 | + */ | |
| 38 | + List<ProcessInstance> getProcessInstances(Set<String> ids); | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * 获得流程实例 Map | |
| 42 | + * | |
| 43 | + * @param ids 流程实例的编号集合 | |
| 44 | + * @return 流程实例列表 Map | |
| 45 | + */ | |
| 46 | + default Map<String, ProcessInstance> getProcessInstanceMap(Set<String> ids) { | |
| 47 | + return CollectionUtils.convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId); | |
| 48 | + } | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * 获得流程实例的分页 | |
| 52 | + * | |
| 53 | + * @param userId 用户编号 | |
| 54 | + * @param pageReqVO 分页请求 | |
| 55 | + * @return 流程实例的分页 | |
| 56 | + */ | |
| 57 | + PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, | |
| 58 | + @Valid BpmProcessInstanceMyPageReqVO pageReqVO); | |
| 59 | + /** | |
| 60 | + * 创建流程实例(提供给前端) | |
| 61 | + * | |
| 62 | + * @param userId 用户编号 | |
| 63 | + * @param createReqVO 创建信息 | |
| 64 | + * @return 实例的编号 | |
| 65 | + */ | |
| 66 | + String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO); | |
| 67 | + | |
| 68 | + /** | |
| 69 | + * 创建流程实例(提供给内部) | |
| 70 | + * | |
| 71 | + * @param userId 用户编号 | |
| 72 | + * @param createReqDTO 创建信息 | |
| 73 | + * @return 实例的编号 | |
| 74 | + */ | |
| 75 | + String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO); | |
| 76 | + | |
| 77 | + /** | |
| 78 | + * 获得流程实例 VO 信息 | |
| 79 | + * | |
| 80 | + * @param id 流程实例的编号 | |
| 81 | + * @return 流程实例 | |
| 82 | + */ | |
| 83 | + BpmProcessInstanceRespVO getProcessInstanceVO(String id); | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * 取消流程实例 | |
| 87 | + * | |
| 88 | + * @param userId 用户编号 | |
| 89 | + * @param cancelReqVO 取消信息 | |
| 90 | + */ | |
| 91 | + void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO); | |
| 92 | + | |
| 93 | + /** | |
| 94 | + * 获得历史的流程实例 | |
| 95 | + * | |
| 96 | + * @param id 流程实例的编号 | |
| 97 | + * @return 历史的流程实例 | |
| 98 | + */ | |
| 99 | + HistoricProcessInstance getHistoricProcessInstance(String id); | |
| 100 | + | |
| 101 | + /** | |
| 102 | + * 获得历史的流程实例列表 | |
| 103 | + * | |
| 104 | + * @param ids 流程实例的编号集合 | |
| 105 | + * @return 历史的流程实例列表 | |
| 106 | + */ | |
| 107 | + List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids); | |
| 108 | + | |
| 109 | + /** | |
| 110 | + * 获得历史的流程实例 Map | |
| 111 | + * | |
| 112 | + * @param ids 流程实例的编号集合 | |
| 113 | + * @return 历史的流程实例列表 Map | |
| 114 | + */ | |
| 115 | + default Map<String, HistoricProcessInstance> getHistoricProcessInstanceMap(Set<String> ids) { | |
| 116 | + return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId); | |
| 117 | + } | |
| 118 | + | |
| 119 | + /** | |
| 120 | + * 创建 ProcessInstance 拓展记录 | |
| 121 | + * | |
| 122 | + * @param instance 流程任务 | |
| 123 | + */ | |
| 124 | + void createProcessInstanceExt(ProcessInstance instance); | |
| 125 | + | |
| 126 | + /** | |
| 127 | + * 更新 ProcessInstance 拓展记录为取消 | |
| 128 | + * | |
| 129 | + * @param event 流程取消事件 | |
| 130 | + */ | |
| 131 | + void updateProcessInstanceExtCancel(FlowableCancelledEvent event); | |
| 132 | + | |
| 133 | + /** | |
| 134 | + * 更新 ProcessInstance 拓展记录为完成 | |
| 135 | + * | |
| 136 | + * @param instance 流程任务 | |
| 137 | + */ | |
| 138 | + void updateProcessInstanceExtComplete(ProcessInstance instance); | |
| 139 | + | |
| 140 | + /** | |
| 141 | + * 更新 ProcessInstance 拓展记录为不通过 | |
| 142 | + * | |
| 143 | + * @param id 流程编号 | |
| 144 | + * @param comment 理由。例如说,审批不通过时,需要传递该值 | |
| 145 | + */ | |
| 146 | + void updateProcessInstanceExtReject(String id, String comment); | |
| 147 | + | |
| 148 | + | |
| 149 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.lang.Assert; | |
| 5 | +import cn.hutool.core.util.StrUtil; | |
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 7 | +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | |
| 8 | +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; | |
| 10 | +import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; | |
| 11 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; | |
| 12 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; | |
| 13 | +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; | |
| 14 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; | |
| 15 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 16 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; | |
| 17 | +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; | |
| 18 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; | |
| 19 | +import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; | |
| 20 | +import cn.iocoder.yudao.module.system.api.dept.DeptApi; | |
| 21 | +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | |
| 22 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 23 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 24 | +import lombok.extern.slf4j.Slf4j; | |
| 25 | +import org.flowable.engine.HistoryService; | |
| 26 | +import org.flowable.engine.RuntimeService; | |
| 27 | +import org.flowable.engine.delegate.event.FlowableCancelledEvent; | |
| 28 | +import org.flowable.engine.history.HistoricProcessInstance; | |
| 29 | +import org.flowable.engine.repository.ProcessDefinition; | |
| 30 | +import org.flowable.engine.runtime.ProcessInstance; | |
| 31 | +import org.flowable.task.api.Task; | |
| 32 | +import org.springframework.context.annotation.Lazy; | |
| 33 | +import org.springframework.scheduling.annotation.Async; | |
| 34 | +import org.springframework.stereotype.Service; | |
| 35 | +import org.springframework.transaction.annotation.Transactional; | |
| 36 | +import org.springframework.validation.annotation.Validated; | |
| 37 | + | |
| 38 | +import javax.annotation.Resource; | |
| 39 | +import javax.validation.Valid; | |
| 40 | +import java.util.*; | |
| 41 | + | |
| 42 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 43 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 44 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; | |
| 45 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF; | |
| 46 | + | |
| 47 | +/** | |
| 48 | + * 流程实例 Service 实现类 | |
| 49 | + * | |
| 50 | + * ProcessDefinition & ProcessInstance & Execution & Task 的关系: | |
| 51 | + * 1. https://blog.csdn.net/bobozai86/article/details/105210414 | |
| 52 | + * | |
| 53 | + * HistoricProcessInstance & ProcessInstance 的关系: | |
| 54 | + * 1.https://my.oschina.net/843294669/blog/719024 | |
| 55 | + * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 | |
| 56 | + * | |
| 57 | + * @author 芋道源码 | |
| 58 | + */ | |
| 59 | +@Service | |
| 60 | +@Validated | |
| 61 | +@Slf4j | |
| 62 | +public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { | |
| 63 | + | |
| 64 | + @Resource | |
| 65 | + private RuntimeService runtimeService; | |
| 66 | + @Resource | |
| 67 | + private BpmProcessInstanceExtMapper processInstanceExtMapper; | |
| 68 | + @Resource | |
| 69 | + @Lazy // 解决循环依赖 | |
| 70 | + private BpmTaskService taskService; | |
| 71 | + @Resource | |
| 72 | + private BpmProcessDefinitionService processDefinitionService; | |
| 73 | + @Resource | |
| 74 | + private HistoryService historyService; | |
| 75 | + @Resource | |
| 76 | + private AdminUserApi adminUserApi; | |
| 77 | + @Resource | |
| 78 | + private DeptApi deptApi; | |
| 79 | + @Resource | |
| 80 | + private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; | |
| 81 | + @Resource | |
| 82 | + private BpmMessageService messageService; | |
| 83 | + @Override | |
| 84 | + public ProcessInstance getProcessInstance(String id) { | |
| 85 | + return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); | |
| 86 | + } | |
| 87 | + | |
| 88 | + @Override | |
| 89 | + public List<ProcessInstance> getProcessInstances(Set<String> ids) { | |
| 90 | + return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); | |
| 91 | + } | |
| 92 | + | |
| 93 | + @Override | |
| 94 | + public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, | |
| 95 | + BpmProcessInstanceMyPageReqVO pageReqVO) { | |
| 96 | + // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 | |
| 97 | + PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); | |
| 98 | + if (CollUtil.isEmpty(pageResult.getList())) { | |
| 99 | + return new PageResult<>(pageResult.getTotal()); | |
| 100 | + } | |
| 101 | + | |
| 102 | + // 获得流程 Task Map | |
| 103 | + List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); | |
| 104 | + Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); | |
| 105 | + // 转换返回 | |
| 106 | + return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap); | |
| 107 | + } | |
| 108 | + | |
| 109 | + @Override | |
| 110 | + @Transactional(rollbackFor = Exception.class) | |
| 111 | + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { | |
| 112 | + // 获得流程定义 | |
| 113 | + ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); | |
| 114 | + // 发起流程 | |
| 115 | + return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); | |
| 116 | + } | |
| 117 | + | |
| 118 | + @Override | |
| 119 | + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { | |
| 120 | + // 获得流程定义 | |
| 121 | + ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); | |
| 122 | + // 发起流程 | |
| 123 | + return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); | |
| 124 | + } | |
| 125 | + | |
| 126 | + @Override | |
| 127 | + public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { | |
| 128 | + // 获得流程实例 | |
| 129 | + HistoricProcessInstance processInstance = getHistoricProcessInstance(id); | |
| 130 | + if (processInstance == null) { | |
| 131 | + return null; | |
| 132 | + } | |
| 133 | + BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); | |
| 134 | + Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); | |
| 135 | + | |
| 136 | + // 获得流程定义 | |
| 137 | + ProcessDefinition processDefinition = processDefinitionService | |
| 138 | + .getProcessDefinition(processInstance.getProcessDefinitionId()); | |
| 139 | + Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); | |
| 140 | + BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( | |
| 141 | + processInstance.getProcessDefinitionId()); | |
| 142 | + Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); | |
| 143 | + String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); | |
| 144 | + | |
| 145 | + // 获得 User | |
| 146 | + AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())); | |
| 147 | + DeptRespDTO dept = null; | |
| 148 | + if (startUser != null) { | |
| 149 | + dept = deptApi.getDept(startUser.getDeptId()); | |
| 150 | + } | |
| 151 | + | |
| 152 | + // 拼接结果 | |
| 153 | + return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, | |
| 154 | + processDefinition, processDefinitionExt, bpmnXml, startUser, dept); | |
| 155 | + } | |
| 156 | + | |
| 157 | + @Override | |
| 158 | + public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { | |
| 159 | + // 校验流程实例存在 | |
| 160 | + ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); | |
| 161 | + if (instance == null) { | |
| 162 | + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); | |
| 163 | + } | |
| 164 | + // 只能取消自己的 | |
| 165 | + if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { | |
| 166 | + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); | |
| 167 | + } | |
| 168 | + | |
| 169 | + // 通过删除流程实例,实现流程实例的取消, | |
| 170 | + // 删除流程实例,正则执行任务ACT_RU_TASK. 任务会被删除。通过历史表查询 | |
| 171 | + deleteProcessInstance(cancelReqVO.getId(), | |
| 172 | + BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); | |
| 173 | + } | |
| 174 | + | |
| 175 | + /** | |
| 176 | + * 获得历史的流程实例 | |
| 177 | + * | |
| 178 | + * @param id 流程实例的编号 | |
| 179 | + * @return 历史的流程实例 | |
| 180 | + */ | |
| 181 | + @Override | |
| 182 | + public HistoricProcessInstance getHistoricProcessInstance(String id) { | |
| 183 | + return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); | |
| 184 | + } | |
| 185 | + | |
| 186 | + @Override | |
| 187 | + public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { | |
| 188 | + return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); | |
| 189 | + } | |
| 190 | + | |
| 191 | + @Override | |
| 192 | + public void createProcessInstanceExt(ProcessInstance instance) { | |
| 193 | + // 获得流程定义 | |
| 194 | + ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); | |
| 195 | + // 插入 BpmProcessInstanceExtDO 对象 | |
| 196 | + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() | |
| 197 | + .setProcessInstanceId(instance.getId()) | |
| 198 | + .setProcessDefinitionId(definition.getId()) | |
| 199 | + .setName(instance.getProcessDefinitionName()) | |
| 200 | + .setStartUserId(Long.valueOf(instance.getStartUserId())) | |
| 201 | + .setCategory(definition.getCategory()) | |
| 202 | + .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) | |
| 203 | + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); | |
| 204 | + | |
| 205 | + processInstanceExtMapper.insert(instanceExtDO); | |
| 206 | + } | |
| 207 | + | |
| 208 | + @Override | |
| 209 | + public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { | |
| 210 | + // 判断是否为 Reject 不通过。如果是,则不进行更新 | |
| 211 | + if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) { | |
| 212 | + return; | |
| 213 | + } | |
| 214 | + | |
| 215 | + // 需要主动查询,因为 instance 只有 id 属性 | |
| 216 | + // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance | |
| 217 | + HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); | |
| 218 | + // 更新拓展表 | |
| 219 | + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() | |
| 220 | + .setProcessInstanceId(event.getProcessInstanceId()) | |
| 221 | + .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 | |
| 222 | + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) | |
| 223 | + .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); | |
| 224 | + | |
| 225 | + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); | |
| 226 | + | |
| 227 | + // 发送流程实例的状态事件 | |
| 228 | + processInstanceResultEventPublisher.sendProcessInstanceResultEvent( | |
| 229 | + BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); | |
| 230 | + } | |
| 231 | + | |
| 232 | + @Override | |
| 233 | + public void updateProcessInstanceExtComplete(ProcessInstance instance) { | |
| 234 | + // 需要主动查询,因为 instance 只有 id 属性 | |
| 235 | + // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance | |
| 236 | + HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); | |
| 237 | + // 更新拓展表 | |
| 238 | + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() | |
| 239 | + .setProcessInstanceId(instance.getProcessInstanceId()) | |
| 240 | + .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 | |
| 241 | + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) | |
| 242 | + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 | |
| 243 | + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); | |
| 244 | + | |
| 245 | + // 发送流程被通过的消息 | |
| 246 | + messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); | |
| 247 | + | |
| 248 | + // 发送流程实例的状态事件 | |
| 249 | + processInstanceResultEventPublisher.sendProcessInstanceResultEvent( | |
| 250 | + BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); | |
| 251 | + } | |
| 252 | + | |
| 253 | + @Transactional(rollbackFor = Exception.class) | |
| 254 | + public void updateProcessInstanceExtReject(String id, String comment) { | |
| 255 | + // 需要主动查询,因为 instance 只有 id 属性 | |
| 256 | + ProcessInstance processInstance = getProcessInstance(id); | |
| 257 | + // 删除流程实例,以实现驳回任务时,取消整个审批流程 | |
| 258 | + deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(comment))); | |
| 259 | + | |
| 260 | + // 更新 status + result | |
| 261 | + // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, | |
| 262 | + // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 | |
| 263 | + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id) | |
| 264 | + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) | |
| 265 | + .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); | |
| 266 | + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); | |
| 267 | + | |
| 268 | + // 发送流程被不通过的消息 | |
| 269 | + messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, comment)); | |
| 270 | + | |
| 271 | + // 发送流程实例的状态事件 | |
| 272 | + processInstanceResultEventPublisher.sendProcessInstanceResultEvent( | |
| 273 | + BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); | |
| 274 | + } | |
| 275 | + | |
| 276 | + private void deleteProcessInstance(String id, String reason) { | |
| 277 | + runtimeService.deleteProcessInstance(id, reason); | |
| 278 | + } | |
| 279 | + | |
| 280 | + private String createProcessInstance0(Long userId, ProcessDefinition definition, | |
| 281 | + Map<String, Object> variables, String businessKey) { | |
| 282 | + // 校验流程定义 | |
| 283 | + if (definition == null) { | |
| 284 | + throw exception(PROCESS_DEFINITION_NOT_EXISTS); | |
| 285 | + } | |
| 286 | + if (definition.isSuspended()) { | |
| 287 | + throw exception(PROCESS_DEFINITION_IS_SUSPENDED); | |
| 288 | + } | |
| 289 | + | |
| 290 | + // 创建流程实例 | |
| 291 | + ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables); | |
| 292 | + // 设置流程名字 | |
| 293 | + runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); | |
| 294 | + | |
| 295 | + // 补全流程实例的拓展表 | |
| 296 | + //TODO startProcessInstance流程里面修改了 BpmProcessInstanceExt,没有提交,和下面的更新 锁持有冲突了,异步更新这个表 | |
| 297 | +// processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()).setFormVariables(variables)); | |
| 298 | + BpmProcessInstanceExtDO bpmProcessInstanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()).setFormVariables(variables); | |
| 299 | + asyncUpdateProcesInstance(bpmProcessInstanceExtDO); | |
| 300 | + return instance.getId(); | |
| 301 | + } | |
| 302 | + | |
| 303 | + @Async | |
| 304 | + public void asyncUpdateProcesInstance(BpmProcessInstanceExtDO bpmProcessInstanceExtDO){ | |
| 305 | + log.info("asyncUpdateProcesInstance ,cause MySQL Dead Lock"); | |
| 306 | + processInstanceExtMapper.updateByProcessInstanceId(bpmProcessInstanceExtDO); | |
| 307 | + | |
| 308 | + } | |
| 309 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; | |
| 6 | +import org.flowable.task.api.Task; | |
| 7 | + | |
| 8 | + | |
| 9 | +import javax.validation.Valid; | |
| 10 | +import java.util.List; | |
| 11 | +import java.util.Map; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * 流程任务实例 Service 接口 | |
| 15 | + * | |
| 16 | + * @author jason | |
| 17 | + * @author 芋道源码 | |
| 18 | + */ | |
| 19 | +public interface BpmTaskService { | |
| 20 | + /** | |
| 21 | + * 获得待办的流程任务分页 | |
| 22 | + * | |
| 23 | + * @param userId 用户编号 | |
| 24 | + * @param pageReqVO 分页请求 | |
| 25 | + * @return 流程任务分页 | |
| 26 | + */ | |
| 27 | + PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO); | |
| 28 | + /** | |
| 29 | + * 获得已办的流程任务分页 | |
| 30 | + * | |
| 31 | + * @param userId 用户编号 | |
| 32 | + * @param pageReqVO 分页请求 | |
| 33 | + * @return 流程任务分页 | |
| 34 | + */ | |
| 35 | + PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO); | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * 获得流程任务 Map | |
| 39 | + * | |
| 40 | + * @param processInstanceIds 流程实例的编号数组 | |
| 41 | + * @return 流程任务 Map | |
| 42 | + */ | |
| 43 | + default Map<String, List<Task>> getTaskMapByProcessInstanceIds(List<String> processInstanceIds) { | |
| 44 | + return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds), | |
| 45 | + Task::getProcessInstanceId); | |
| 46 | + } | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * 获得流程任务列表 | |
| 50 | + * | |
| 51 | + * @param processInstanceIds 流程实例的编号数组 | |
| 52 | + * @return 流程任务列表 | |
| 53 | + */ | |
| 54 | + List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds); | |
| 55 | + | |
| 56 | + /** | |
| 57 | + * 获得指令流程实例的流程任务列表,包括所有状态的 | |
| 58 | + * | |
| 59 | + * @param processInstanceId 流程实例的编号 | |
| 60 | + * @return 流程任务列表 | |
| 61 | + */ | |
| 62 | + List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId); | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * 通过任务 | |
| 66 | + * | |
| 67 | + * @param userId 用户编号 | |
| 68 | + * @param reqVO 通过请求 | |
| 69 | + */ | |
| 70 | + void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO); | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * 不通过任务 | |
| 74 | + * | |
| 75 | + * @param userId 用户编号 | |
| 76 | + * @param reqVO 不通过请求 | |
| 77 | + */ | |
| 78 | + void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO); | |
| 79 | + /** | |
| 80 | + * 回退任务 | |
| 81 | + * | |
| 82 | + * @param taskId 任务编号 | |
| 83 | + */ | |
| 84 | + void backTask(String taskId,String destinationTaskDefKey); | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * 将流程任务分配给指定用户 | |
| 88 | + * | |
| 89 | + * @param userId 用户编号 | |
| 90 | + * @param reqVO 分配请求 | |
| 91 | + */ | |
| 92 | + void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO); | |
| 93 | + | |
| 94 | + /** | |
| 95 | + * 将流程任务分配给指定用户 | |
| 96 | + * | |
| 97 | + * @param id 流程任务编号 | |
| 98 | + * @param userId 用户编号 | |
| 99 | + */ | |
| 100 | + void updateTaskAssignee(String id, Long userId); | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * 创建 Task 拓展记录 | |
| 104 | + * | |
| 105 | + * @param task 任务实体 | |
| 106 | + */ | |
| 107 | + void createTaskExt(Task task); | |
| 108 | + | |
| 109 | + /** | |
| 110 | + * 更新 Task 拓展记录为完成 | |
| 111 | + * | |
| 112 | + * @param task 任务实体 | |
| 113 | + */ | |
| 114 | + void updateTaskExtComplete(Task task); | |
| 115 | + | |
| 116 | + /** | |
| 117 | + * 更新 Task 拓展记录,并发送通知 | |
| 118 | + * | |
| 119 | + * @param task 任务实体 | |
| 120 | + */ | |
| 121 | + void updateTaskExtAssign(Task task); | |
| 122 | + | |
| 123 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | |
| 7 | +import cn.iocoder.yudao.framework.common.util.object.PageUtils; | |
| 8 | +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; | |
| 9 | +import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; | |
| 10 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; | |
| 11 | +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; | |
| 12 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 13 | +import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; | |
| 14 | +import cn.iocoder.yudao.module.system.api.dept.DeptApi; | |
| 15 | +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | |
| 16 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 17 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 18 | +import lombok.extern.slf4j.Slf4j; | |
| 19 | +import org.flowable.engine.HistoryService; | |
| 20 | +import org.flowable.engine.RuntimeService; | |
| 21 | +import org.flowable.engine.TaskService; | |
| 22 | +import org.flowable.engine.history.HistoricProcessInstance; | |
| 23 | +import org.flowable.engine.runtime.ProcessInstance; | |
| 24 | +import org.flowable.task.api.Task; | |
| 25 | +import org.flowable.task.api.TaskQuery; | |
| 26 | +import org.flowable.task.api.history.HistoricTaskInstance; | |
| 27 | +import org.flowable.task.api.history.HistoricTaskInstanceQuery; | |
| 28 | +import org.springframework.stereotype.Service; | |
| 29 | +import org.springframework.transaction.annotation.Transactional; | |
| 30 | +import org.springframework.transaction.support.TransactionSynchronization; | |
| 31 | +import org.springframework.transaction.support.TransactionSynchronizationManager; | |
| 32 | + | |
| 33 | +import javax.annotation.Resource; | |
| 34 | +import javax.validation.Valid; | |
| 35 | +import java.util.*; | |
| 36 | + | |
| 37 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 38 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | |
| 39 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 40 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; | |
| 41 | + | |
| 42 | +/** | |
| 43 | + * 流程任务实例 Service 实现类 | |
| 44 | + * | |
| 45 | + * @author 芋道源码 | |
| 46 | + * @author jason | |
| 47 | + */ | |
| 48 | +@Slf4j | |
| 49 | +@Service | |
| 50 | +public class BpmTaskServiceImpl implements BpmTaskService{ | |
| 51 | + | |
| 52 | + @Resource | |
| 53 | + private TaskService taskService; | |
| 54 | + @Resource | |
| 55 | + private RuntimeService runtimeService; | |
| 56 | + @Resource | |
| 57 | + private HistoryService historyService; | |
| 58 | + | |
| 59 | + @Resource | |
| 60 | + private BpmProcessInstanceService processInstanceService; | |
| 61 | + @Resource | |
| 62 | + private AdminUserApi adminUserApi; | |
| 63 | + @Resource | |
| 64 | + private DeptApi deptApi; | |
| 65 | + @Resource | |
| 66 | + private BpmTaskExtMapper taskExtMapper; | |
| 67 | + @Resource | |
| 68 | + private BpmMessageService messageService; | |
| 69 | + | |
| 70 | + @Override | |
| 71 | + public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { | |
| 72 | + // 查询待办任务 | |
| 73 | + TaskQuery taskQuery = taskService.createTaskQuery() | |
| 74 | + .taskAssignee(String.valueOf(userId)) // 分配给自己 | |
| 75 | + .orderByTaskCreateTime().desc(); // 创建时间倒序 | |
| 76 | + if (StrUtil.isNotBlank(pageVO.getName())) { | |
| 77 | + taskQuery.taskNameLike("%" + pageVO.getName() + "%"); | |
| 78 | + } | |
| 79 | + if (pageVO.getBeginCreateTime() != null) { | |
| 80 | + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime()); | |
| 81 | + } | |
| 82 | + if (pageVO.getEndCreateTime() != null) { | |
| 83 | + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime()); | |
| 84 | + } | |
| 85 | + // 执行查询 | |
| 86 | + List<Task> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); | |
| 87 | + if (CollUtil.isEmpty(tasks)) { | |
| 88 | + return PageResult.empty(taskQuery.count()); | |
| 89 | + } | |
| 90 | + | |
| 91 | + // 获得 ProcessInstance Map | |
| 92 | + Map<String, ProcessInstance> processInstanceMap = processInstanceService.getProcessInstanceMap( | |
| 93 | + convertSet(tasks, Task::getProcessInstanceId)); | |
| 94 | + // 获得 User Map | |
| 95 | + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( | |
| 96 | + convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); | |
| 97 | + // 拼接结果 | |
| 98 | + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList1(tasks, processInstanceMap, userMap), | |
| 99 | + taskQuery.count()); | |
| 100 | + } | |
| 101 | + | |
| 102 | + @Override | |
| 103 | + public PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) { | |
| 104 | + // 查询已办任务 | |
| 105 | + HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery() | |
| 106 | + .finished() // 已完成 | |
| 107 | + .taskAssignee(String.valueOf(userId)) // 分配给自己 | |
| 108 | + .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序 | |
| 109 | + if (StrUtil.isNotBlank(pageVO.getName())) { | |
| 110 | + taskQuery.taskNameLike("%" + pageVO.getName() + "%"); | |
| 111 | + } | |
| 112 | + if (pageVO.getBeginCreateTime() != null) { | |
| 113 | + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime()); | |
| 114 | + } | |
| 115 | + if (pageVO.getEndCreateTime() != null) { | |
| 116 | + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime()); | |
| 117 | + } | |
| 118 | + // 执行查询 | |
| 119 | + List<HistoricTaskInstance> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); | |
| 120 | + if (CollUtil.isEmpty(tasks)) { | |
| 121 | + return PageResult.empty(taskQuery.count()); | |
| 122 | + } | |
| 123 | + | |
| 124 | + // 获得 TaskExtDO Map | |
| 125 | + List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId)); | |
| 126 | + Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId); | |
| 127 | + // 获得 ProcessInstance Map | |
| 128 | + Map<String, HistoricProcessInstance> historicProcessInstanceMap = processInstanceService.getHistoricProcessInstanceMap( | |
| 129 | + convertSet(tasks, HistoricTaskInstance::getProcessInstanceId)); | |
| 130 | + // 获得 User Map | |
| 131 | + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( | |
| 132 | + convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); | |
| 133 | + // 拼接结果 | |
| 134 | + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap), | |
| 135 | + taskQuery.count()); | |
| 136 | + } | |
| 137 | + | |
| 138 | + @Override | |
| 139 | + public List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds) { | |
| 140 | + if (CollUtil.isEmpty(processInstanceIds)) { | |
| 141 | + return Collections.emptyList(); | |
| 142 | + } | |
| 143 | + return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list(); | |
| 144 | + } | |
| 145 | + | |
| 146 | + @Override | |
| 147 | + public List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId) { | |
| 148 | + // 获得任务列表 | |
| 149 | + List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery() | |
| 150 | + .processInstanceId(processInstanceId) | |
| 151 | + .orderByHistoricTaskInstanceStartTime().desc() // 创建时间倒序 | |
| 152 | + .list(); | |
| 153 | + if (CollUtil.isEmpty(tasks)) { | |
| 154 | + return Collections.emptyList(); | |
| 155 | + } | |
| 156 | + | |
| 157 | + // 获得 TaskExtDO Map | |
| 158 | + List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId)); | |
| 159 | + Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId); | |
| 160 | + // 获得 ProcessInstance Map | |
| 161 | + HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId); | |
| 162 | + // 获得 User Map | |
| 163 | + Set<Long> userIds = convertSet(tasks, task -> NumberUtils.parseLong(task.getAssignee())); | |
| 164 | + userIds.add(NumberUtils.parseLong(processInstance.getStartUserId())); | |
| 165 | + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); | |
| 166 | + // 获得 Dept Map | |
| 167 | + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); | |
| 168 | + | |
| 169 | + // 拼接数据 | |
| 170 | + return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap); | |
| 171 | + } | |
| 172 | + | |
| 173 | + @Override | |
| 174 | + @Transactional(rollbackFor = Exception.class) | |
| 175 | + public void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO) { | |
| 176 | + // 校验任务存在 | |
| 177 | + Task task = checkTask(userId, reqVO.getId()); | |
| 178 | + // 校验流程实例存在 | |
| 179 | + ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); | |
| 180 | + if (instance == null) { | |
| 181 | + throw exception(PROCESS_INSTANCE_NOT_EXISTS); | |
| 182 | + } | |
| 183 | + | |
| 184 | + // 完成任务,审批通过 | |
| 185 | + taskService.complete(task.getId(), instance.getProcessVariables()); | |
| 186 | + // 更新任务拓展表为通过 | |
| 187 | + taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) | |
| 188 | + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setComment(reqVO.getComment())); | |
| 189 | + } | |
| 190 | + | |
| 191 | + @Override | |
| 192 | + @Transactional(rollbackFor = Exception.class) | |
| 193 | + public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) { | |
| 194 | + Task task = checkTask(userId, reqVO.getId()); | |
| 195 | + // 校验流程实例存在 | |
| 196 | + ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); | |
| 197 | + if (instance == null) { | |
| 198 | + throw exception(PROCESS_INSTANCE_NOT_EXISTS); | |
| 199 | + } | |
| 200 | + | |
| 201 | + // 更新流程实例为不通过 | |
| 202 | + processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getComment()); | |
| 203 | + | |
| 204 | + // 更新任务拓展表为不通过 | |
| 205 | + taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) | |
| 206 | + .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment())); | |
| 207 | + } | |
| 208 | + | |
| 209 | + @Override | |
| 210 | + public void backTask(String taskId,String destinationTaskDefKey) { | |
| 211 | + Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult(); | |
| 212 | + | |
| 213 | + runtimeService.createChangeActivityStateBuilder() | |
| 214 | + .processInstanceId(currentTask.getProcessInstanceId()) | |
| 215 | + .moveActivityIdTo(currentTask.getTaskDefinitionKey(), destinationTaskDefKey) | |
| 216 | + .changeState(); | |
| 217 | + } | |
| 218 | + | |
| 219 | + @Override | |
| 220 | + public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) { | |
| 221 | + // 校验任务存在 | |
| 222 | + Task task = checkTask(userId, reqVO.getId()); | |
| 223 | + // 更新负责人 | |
| 224 | + updateTaskAssignee(task.getId(), reqVO.getAssigneeUserId()); | |
| 225 | + } | |
| 226 | + | |
| 227 | + @Override | |
| 228 | + public void updateTaskAssignee(String id, Long userId) { | |
| 229 | + taskService.setAssignee(id, String.valueOf(userId)); | |
| 230 | + } | |
| 231 | + | |
| 232 | + | |
| 233 | + @Override | |
| 234 | + public void createTaskExt(Task task) { | |
| 235 | + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task) | |
| 236 | + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); | |
| 237 | + taskExtMapper.insert(taskExtDO); | |
| 238 | + } | |
| 239 | + | |
| 240 | + @Override | |
| 241 | + public void updateTaskExtComplete(Task task) { | |
| 242 | + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task) | |
| 243 | + .setEndTime(new Date()); | |
| 244 | + taskExtMapper.updateByTaskId(taskExtDO); | |
| 245 | + } | |
| 246 | + | |
| 247 | + @Override | |
| 248 | + public void updateTaskExtAssign(Task task) { | |
| 249 | + BpmTaskExtDO taskExtDO = new BpmTaskExtDO() | |
| 250 | + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())) | |
| 251 | + .setTaskId(task.getId()); | |
| 252 | + taskExtMapper.updateByTaskId(taskExtDO); | |
| 253 | + // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。 | |
| 254 | + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { | |
| 255 | + @Override | |
| 256 | + public void afterCommit() { | |
| 257 | + ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); | |
| 258 | + AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId())); | |
| 259 | + messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task)); | |
| 260 | + } | |
| 261 | + }); | |
| 262 | + } | |
| 263 | + | |
| 264 | + /** | |
| 265 | + * 校验任务是否存在, 并且是否是分配给自己的任务 | |
| 266 | + * @param userId 用户 id | |
| 267 | + * @param taskId task id | |
| 268 | + */ | |
| 269 | + private Task checkTask(Long userId, String taskId) { | |
| 270 | + Task task = getTask(taskId); | |
| 271 | + if (task == null) { | |
| 272 | + throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); | |
| 273 | + } | |
| 274 | + if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) { | |
| 275 | + throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF); | |
| 276 | + } | |
| 277 | + return task; | |
| 278 | + } | |
| 279 | + | |
| 280 | + private Task getTask(String id) { | |
| 281 | + return taskService.createTaskQuery().taskId(id).singleResult(); | |
| 282 | + } | |
| 283 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task; | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.RandomUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 6 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 7 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO; | |
| 10 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | |
| 11 | +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmFormMapper; | |
| 12 | +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmFormFieldRespDTO; | |
| 13 | +import org.junit.jupiter.api.Test; | |
| 14 | +import org.springframework.context.annotation.Import; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | +import java.util.List; | |
| 18 | +import java.util.stream.Collectors; | |
| 19 | +import java.util.stream.Stream; | |
| 20 | + | |
| 21 | +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; | |
| 22 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | |
| 23 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | |
| 24 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; | |
| 25 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 26 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.FORM_NOT_EXISTS; | |
| 27 | +import static org.junit.jupiter.api.Assertions.*; | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * {@link BpmFormServiceImpl} 的单元测试类 | |
| 31 | + * | |
| 32 | + * @author 芋道源码 | |
| 33 | + */ | |
| 34 | +@Import(BpmFormServiceImpl.class) | |
| 35 | +public class BpmFormServiceTest extends BaseDbUnitTest { | |
| 36 | + | |
| 37 | + @Resource | |
| 38 | + private BpmFormServiceImpl formService; | |
| 39 | + | |
| 40 | + @Resource | |
| 41 | + private BpmFormMapper formMapper; | |
| 42 | + | |
| 43 | + @Test | |
| 44 | + public void testCreateForm_success() { | |
| 45 | + // 准备参数 | |
| 46 | + BpmFormCreateReqVO reqVO = randomPojo(BpmFormCreateReqVO.class, o -> { | |
| 47 | + o.setConf("{}"); | |
| 48 | + o.setFields(randomFields()); | |
| 49 | + }); | |
| 50 | + | |
| 51 | + // 调用 | |
| 52 | + Long formId = formService.createForm(reqVO); | |
| 53 | + // 断言 | |
| 54 | + assertNotNull(formId); | |
| 55 | + // 校验记录的属性是否正确 | |
| 56 | + BpmFormDO form = formMapper.selectById(formId); | |
| 57 | + assertPojoEquals(reqVO, form); | |
| 58 | + } | |
| 59 | + | |
| 60 | + @Test | |
| 61 | + public void testUpdateForm_success() { | |
| 62 | + // mock 数据 | |
| 63 | + BpmFormDO dbForm = randomPojo(BpmFormDO.class, o -> { | |
| 64 | + o.setConf("{}"); | |
| 65 | + o.setFields(randomFields()); | |
| 66 | + }); | |
| 67 | + formMapper.insert(dbForm);// @Sql: 先插入出一条存在的数据 | |
| 68 | + // 准备参数 | |
| 69 | + BpmFormUpdateReqVO reqVO = randomPojo(BpmFormUpdateReqVO.class, o -> { | |
| 70 | + o.setId(dbForm.getId()); // 设置更新的 ID | |
| 71 | + o.setConf("{'yudao': 'yuanma'}"); | |
| 72 | + o.setFields(randomFields()); | |
| 73 | + }); | |
| 74 | + | |
| 75 | + // 调用 | |
| 76 | + formService.updateForm(reqVO); | |
| 77 | + // 校验是否更新正确 | |
| 78 | + BpmFormDO form = formMapper.selectById(reqVO.getId()); // 获取最新的 | |
| 79 | + assertPojoEquals(reqVO, form); | |
| 80 | + } | |
| 81 | + | |
| 82 | + @Test | |
| 83 | + public void testUpdateForm_notExists() { | |
| 84 | + // 准备参数 | |
| 85 | + BpmFormUpdateReqVO reqVO = randomPojo(BpmFormUpdateReqVO.class, o -> { | |
| 86 | + o.setConf("{'yudao': 'yuanma'}"); | |
| 87 | + o.setFields(randomFields()); | |
| 88 | + }); | |
| 89 | + | |
| 90 | + // 调用, 并断言异常 | |
| 91 | + assertServiceException(() -> formService.updateForm(reqVO), FORM_NOT_EXISTS); | |
| 92 | + } | |
| 93 | + | |
| 94 | + @Test | |
| 95 | + public void testDeleteForm_success() { | |
| 96 | + // mock 数据 | |
| 97 | + BpmFormDO dbForm = randomPojo(BpmFormDO.class); | |
| 98 | + formMapper.insert(dbForm);// @Sql: 先插入出一条存在的数据 | |
| 99 | + // 准备参数 | |
| 100 | + Long id = dbForm.getId(); | |
| 101 | + | |
| 102 | + // 调用 | |
| 103 | + formService.deleteForm(id); | |
| 104 | + // 校验数据不存在了 | |
| 105 | + assertNull(formMapper.selectById(id)); | |
| 106 | + } | |
| 107 | + | |
| 108 | + @Test | |
| 109 | + public void testDeleteForm_notExists() { | |
| 110 | + // 准备参数 | |
| 111 | + Long id = randomLongId(); | |
| 112 | + | |
| 113 | + // 调用, 并断言异常 | |
| 114 | + assertServiceException(() -> formService.deleteForm(id), FORM_NOT_EXISTS); | |
| 115 | + } | |
| 116 | + | |
| 117 | + @Test | |
| 118 | + public void testGetFormPage() { | |
| 119 | + // mock 数据 | |
| 120 | + BpmFormDO dbForm = randomPojo(BpmFormDO.class, o -> { // 等会查询到 | |
| 121 | + o.setName("芋道源码"); | |
| 122 | + }); | |
| 123 | + formMapper.insert(dbForm); | |
| 124 | + // 测试 name 不匹配 | |
| 125 | + formMapper.insert(cloneIgnoreId(dbForm, o -> o.setName("源码"))); | |
| 126 | + // 准备参数 | |
| 127 | + BpmFormPageReqVO reqVO = new BpmFormPageReqVO(); | |
| 128 | + reqVO.setName("芋道"); | |
| 129 | + | |
| 130 | + // 调用 | |
| 131 | + PageResult<BpmFormDO> pageResult = formService.getFormPage(reqVO); | |
| 132 | + // 断言 | |
| 133 | + assertEquals(1, pageResult.getTotal()); | |
| 134 | + assertEquals(1, pageResult.getList().size()); | |
| 135 | + assertPojoEquals(dbForm, pageResult.getList().get(0)); | |
| 136 | + } | |
| 137 | + | |
| 138 | + private List<String> randomFields() { | |
| 139 | + int size = RandomUtil.randomInt(1, 3); | |
| 140 | + return Stream.iterate(0, i -> i).limit(size) | |
| 141 | + .map(i -> JsonUtils.toJsonString(randomPojo(BpmFormFieldRespDTO.class))) | |
| 142 | + .collect(Collectors.toList()); | |
| 143 | + } | |
| 144 | + | |
| 145 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.definition; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.date.DateUtils; | |
| 6 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 7 | +import cn.iocoder.yudao.framework.test.core.util.AssertUtils; | |
| 8 | +import cn.iocoder.yudao.framework.test.core.util.RandomUtils; | |
| 9 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO; | |
| 10 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO; | |
| 11 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO; | |
| 12 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | |
| 13 | +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmUserGroupMapper; | |
| 14 | +import org.junit.jupiter.api.Assertions; | |
| 15 | +import org.junit.jupiter.api.Test; | |
| 16 | +import org.springframework.context.annotation.Import; | |
| 17 | + | |
| 18 | +import javax.annotation.Resource; | |
| 19 | + | |
| 20 | +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; | |
| 21 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.USER_GROUP_NOT_EXISTS; | |
| 22 | + | |
| 23 | +/** | |
| 24 | +* {@link BpmUserGroupServiceImpl} 的单元测试类 | |
| 25 | +* | |
| 26 | +* @author 芋道源码 | |
| 27 | +*/ | |
| 28 | +@Import(BpmUserGroupServiceImpl.class) | |
| 29 | +public class BpmUserGroupServiceTest extends BaseDbUnitTest { | |
| 30 | + | |
| 31 | + @Resource | |
| 32 | + private BpmUserGroupServiceImpl userGroupService; | |
| 33 | + | |
| 34 | + @Resource | |
| 35 | + private BpmUserGroupMapper userGroupMapper; | |
| 36 | + | |
| 37 | + @Test | |
| 38 | + public void testCreateUserGroup_success() { | |
| 39 | + // 准备参数 | |
| 40 | + BpmUserGroupCreateReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupCreateReqVO.class); | |
| 41 | + | |
| 42 | + // 调用 | |
| 43 | + Long userGroupId = userGroupService.createUserGroup(reqVO); | |
| 44 | + // 断言 | |
| 45 | + Assertions.assertNotNull(userGroupId); | |
| 46 | + // 校验记录的属性是否正确 | |
| 47 | + BpmUserGroupDO userGroup = userGroupMapper.selectById(userGroupId); | |
| 48 | + AssertUtils.assertPojoEquals(reqVO, userGroup); | |
| 49 | + } | |
| 50 | + | |
| 51 | + @Test | |
| 52 | + public void testUpdateUserGroup_success() { | |
| 53 | + // mock 数据 | |
| 54 | + BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class); | |
| 55 | + userGroupMapper.insert(dbUserGroup);// @Sql: 先插入出一条存在的数据 | |
| 56 | + // 准备参数 | |
| 57 | + BpmUserGroupUpdateReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupUpdateReqVO.class, o -> { | |
| 58 | + o.setId(dbUserGroup.getId()); // 设置更新的 ID | |
| 59 | + }); | |
| 60 | + | |
| 61 | + // 调用 | |
| 62 | + userGroupService.updateUserGroup(reqVO); | |
| 63 | + // 校验是否更新正确 | |
| 64 | + BpmUserGroupDO userGroup = userGroupMapper.selectById(reqVO.getId()); // 获取最新的 | |
| 65 | + AssertUtils.assertPojoEquals(reqVO, userGroup); | |
| 66 | + } | |
| 67 | + | |
| 68 | + @Test | |
| 69 | + public void testUpdateUserGroup_notExists() { | |
| 70 | + // 准备参数 | |
| 71 | + BpmUserGroupUpdateReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupUpdateReqVO.class); | |
| 72 | + | |
| 73 | + // 调用, 并断言异常 | |
| 74 | + AssertUtils.assertServiceException(() -> userGroupService.updateUserGroup(reqVO), USER_GROUP_NOT_EXISTS); | |
| 75 | + } | |
| 76 | + | |
| 77 | + @Test | |
| 78 | + public void testDeleteUserGroup_success() { | |
| 79 | + // mock 数据 | |
| 80 | + BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class); | |
| 81 | + userGroupMapper.insert(dbUserGroup);// @Sql: 先插入出一条存在的数据 | |
| 82 | + // 准备参数 | |
| 83 | + Long id = dbUserGroup.getId(); | |
| 84 | + | |
| 85 | + // 调用 | |
| 86 | + userGroupService.deleteUserGroup(id); | |
| 87 | + // 校验数据不存在了 | |
| 88 | + Assertions.assertNull(userGroupMapper.selectById(id)); | |
| 89 | + } | |
| 90 | + | |
| 91 | + @Test | |
| 92 | + public void testDeleteUserGroup_notExists() { | |
| 93 | + // 准备参数 | |
| 94 | + Long id = RandomUtils.randomLongId(); | |
| 95 | + | |
| 96 | + // 调用, 并断言异常 | |
| 97 | + AssertUtils.assertServiceException(() -> userGroupService.deleteUserGroup(id), USER_GROUP_NOT_EXISTS); | |
| 98 | + } | |
| 99 | + | |
| 100 | + @Test | |
| 101 | + public void testGetUserGroupPage() { | |
| 102 | + // mock 数据 | |
| 103 | + BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class, o -> { // 等会查询到 | |
| 104 | + o.setName("芋道源码"); | |
| 105 | + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 106 | + o.setCreateTime(DateUtils.buildTime(2021, 11, 11)); | |
| 107 | + }); | |
| 108 | + userGroupMapper.insert(dbUserGroup); | |
| 109 | + // 测试 name 不匹配 | |
| 110 | + userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setName("芋道"))); | |
| 111 | + // 测试 status 不匹配 | |
| 112 | + userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); | |
| 113 | + // 测试 createTime 不匹配 | |
| 114 | + userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setCreateTime(DateUtils.buildTime(2021, 12, 12)))); | |
| 115 | + // 准备参数 | |
| 116 | + BpmUserGroupPageReqVO reqVO = new BpmUserGroupPageReqVO(); | |
| 117 | + reqVO.setName("源码"); | |
| 118 | + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 119 | + reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 11, 10)); | |
| 120 | + reqVO.setEndCreateTime(DateUtils.buildTime(2021, 11, 12)); | |
| 121 | + | |
| 122 | + // 调用 | |
| 123 | + PageResult<BpmUserGroupDO> pageResult = userGroupService.getUserGroupPage(reqVO); | |
| 124 | + // 断言 | |
| 125 | + Assertions.assertEquals(1, pageResult.getTotal()); | |
| 126 | + Assertions.assertEquals(1, pageResult.getList().size()); | |
| 127 | + AssertUtils.assertPojoEquals(dbUserGroup, pageResult.getList().get(0)); | |
| 128 | + } | |
| 129 | + | |
| 130 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml
0 → 100644
| 1 | +spring: | |
| 2 | + main: | |
| 3 | + lazy-initialization: true # 开启懒加载,加快速度 | |
| 4 | + banner-mode: off # 单元测试,禁用 Banner | |
| 5 | + | |
| 6 | +--- #################### 数据库相关配置 #################### | |
| 7 | + | |
| 8 | +spring: | |
| 9 | + # 数据源配置项 | |
| 10 | + datasource: | |
| 11 | + name: ruoyi-vue-pro | |
| 12 | + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 | |
| 13 | + driver-class-name: org.h2.Driver | |
| 14 | + username: sa | |
| 15 | + password: | |
| 16 | + druid: | |
| 17 | + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 | |
| 18 | + initial-size: 1 # 单元测试,配置为 1,提升启动速度 | |
| 19 | + sql: | |
| 20 | + init: | |
| 21 | + schema-locations: classpath:/sql/create_tables.sql | |
| 22 | + | |
| 23 | +mybatis: | |
| 24 | + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 | |
| 25 | + | |
| 26 | +--- #################### 定时任务相关配置 #################### | |
| 27 | + | |
| 28 | +--- #################### 配置中心相关配置 #################### | |
| 29 | + | |
| 30 | +--- #################### 服务保障相关配置 #################### | |
| 31 | + | |
| 32 | +# Lock4j 配置项(单元测试,禁用 Lock4j) | |
| 33 | + | |
| 34 | +# Resilience4j 配置项 | |
| 35 | + | |
| 36 | +--- #################### 监控相关配置 #################### | |
| 37 | + | |
| 38 | +--- #################### 芋道相关配置 #################### | |
| 39 | + | |
| 40 | +# 芋道配置项,设置当前项目所有自定义的配置 | |
| 41 | +yudao: | |
| 42 | + info: | |
| 43 | + base-package: cn.iocoder.yudao.module | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/logback.xml
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/sql/clean.sql
0 → 100644
yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/sql/create_tables.sql
0 → 100644
| 1 | +CREATE TABLE IF NOT EXISTS "bpm_user_group" ( | |
| 2 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 3 | + "name" varchar(63) NOT NULL, | |
| 4 | + "description" varchar(255) NOT NULL, | |
| 5 | + "status" tinyint NOT NULL, | |
| 6 | + "member_user_ids" varchar(255) NOT NULL, | |
| 7 | + "creator" varchar(64) DEFAULT '', | |
| 8 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 9 | + "updater" varchar(64) DEFAULT '', | |
| 10 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 11 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 12 | + PRIMARY KEY ("id") | |
| 13 | +) COMMENT '用户组'; | |
| 14 | + | |
| 15 | +CREATE TABLE IF NOT EXISTS "bpm_form" ( | |
| 16 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 17 | + "name" varchar(63) NOT NULL, | |
| 18 | + "status" tinyint NOT NULL, | |
| 19 | + "fields" varchar(255) NOT NULL, | |
| 20 | + "conf" varchar(255) NOT NULL, | |
| 21 | + "remark" varchar(255), | |
| 22 | + "creator" varchar(64) DEFAULT '', | |
| 23 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 24 | + "updater" varchar(64) DEFAULT '', | |
| 25 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 26 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 27 | + PRIMARY KEY ("id") | |
| 28 | +) COMMENT '动态表单'; | ... | ... |
yudao-server/pom.xml
| ... | ... | @@ -45,7 +45,7 @@ |
| 45 | 45 | <!-- 默认引入 yudao-module-bpm-biz-flowable 实现,可以替换为 yudao-module-bpm-biz-activiti 实现--> |
| 46 | 46 | <dependency> |
| 47 | 47 | <groupId>cn.iocoder.boot</groupId> |
| 48 | - <artifactId>yudao-module-bpm-biz-flowable</artifactId> | |
| 48 | + <artifactId>yudao-module-bpm-biz</artifactId> | |
| 49 | 49 | <version>${revision}</version> |
| 50 | 50 | </dependency> |
| 51 | 51 | <!-- <dependency>--> | ... | ... |