Commit 8a3488f3d1fcf55558fa9ce7ef14d777c917fe17
Committed by
Gitee
!62 工作流的流程任务相关
Merge pull request !62 from 芋道源码/feature/activiti
Showing
81 changed files
with
3165 additions
and
2080 deletions
sql/ruoyi-vue-pro.sql
No preview for this file type
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/BpmProcessDefinitionController.http
0 → 100644
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/BpmProcessDefinitionController.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionListReqVO; | |
| 3 | 4 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO; |
| 4 | 5 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageReqVO; |
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionRespVO; | |
| 5 | 7 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; |
| 6 | 8 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 7 | 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| ... | ... | @@ -17,6 +19,8 @@ import org.springframework.web.bind.annotation.RestController; |
| 17 | 19 | |
| 18 | 20 | import javax.annotation.Resource; |
| 19 | 21 | |
| 22 | +import java.util.List; | |
| 23 | + | |
| 20 | 24 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 21 | 25 | |
| 22 | 26 | @Api(tags = "流程定义") |
| ... | ... | @@ -36,14 +40,11 @@ public class BpmProcessDefinitionController { |
| 36 | 40 | return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO)); |
| 37 | 41 | } |
| 38 | 42 | |
| 39 | - // TODO 芋艿:需要重写该方法 | |
| 40 | - @GetMapping(value = "/getStartForm") | |
| 41 | - public CommonResult<String> getStartForm(@RequestParam("processKey") String processKey){ | |
| 42 | -// final ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery(). | |
| 43 | -// processDefinitionKey(processKey).latestVersion().singleResult(); | |
| 44 | -// processRuntime.processDefinition(processDefinition.getId()).getFormKey(); | |
| 45 | - // TODO 这样查似乎有问题??, 暂时写死 | |
| 46 | - return success("/flow/leave/apply"); | |
| 43 | + @GetMapping ("/list") | |
| 44 | + @ApiOperation(value = "获得流程定义列表") | |
| 45 | + public CommonResult<List<BpmProcessDefinitionRespVO>> getProcessDefinitionList( | |
| 46 | + BpmProcessDefinitionListReqVO listReqVO) { | |
| 47 | + return success(bpmDefinitionService.getProcessDefinitionList(listReqVO)); | |
| 47 | 48 | } |
| 48 | 49 | |
| 49 | 50 | @GetMapping ("/get-bpmn-xml") | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TodoTaskPageReqVO.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/BpmProcessDefinitionListReqVO.java
| 1 | -package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo; | |
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo; | |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | 4 | import io.swagger.annotations.ApiModel; |
| 5 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | 6 | import lombok.Data; |
| 6 | 7 | import lombok.EqualsAndHashCode; |
| 7 | 8 | import lombok.ToString; |
| 8 | 9 | |
| 9 | -@ApiModel("待办任务申请分页 Request VO") | |
| 10 | 10 | @Data |
| 11 | -@EqualsAndHashCode(callSuper = true) | |
| 12 | 11 | @ToString(callSuper = true) |
| 13 | -public class TodoTaskPageReqVO extends PageParam { | |
| 12 | +@EqualsAndHashCode(callSuper = true) | |
| 13 | +@ApiModel("流程定义列表 Request VO") | |
| 14 | +public class BpmProcessDefinitionListReqVO extends PageParam { | |
| 15 | + | |
| 16 | + @ApiModelProperty(value = "中断状态", example = "1", notes = "参见 SuspensionState 枚举") | |
| 17 | + private Integer suspensionState; | |
| 14 | 18 | |
| 15 | - private String assignee; | |
| 16 | 19 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/BpmProcessDefinitionPageItemRespVO.java
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.http
| 1 | -### 请求 /login 接口 => 成功 | |
| 1 | +### 请求 /bpm/process-instance/create 接口 => 成功 | |
| 2 | 2 | POST {{baseUrl}}/bpm/process-instance/create |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | tenant-id: 1 |
| 5 | 5 | Authorization: Bearer {{token}} |
| 6 | 6 | |
| 7 | 7 | { |
| 8 | - "processDefinitionId": "leave:7:20ada39c-6c95-11ec-88b1-cacd34981f8e", | |
| 8 | + "processDefinitionId": "gateway_test:2:00e52d8e-701b-11ec-aca9-a2380e71991a", | |
| 9 | 9 | "variables": { |
| 10 | 10 | "a": 1, |
| 11 | 11 | "b": "2" |
| 12 | 12 | } |
| 13 | 13 | } |
| 14 | + | |
| 15 | +### 请求 /bpm/process-instance/cancel 接口 => 成功 | |
| 16 | +DELETE {{baseUrl}}/bpm/process-instance/cancel | |
| 17 | +Content-Type: application/json | |
| 18 | +tenant-id: 1 | |
| 19 | +Authorization: Bearer {{token}} | |
| 20 | + | |
| 21 | +{ | |
| 22 | + "id": "b9220387-7088-11ec-bcae-a2380e71991a", | |
| 23 | + "reason": "我就取消" | |
| 24 | +} | |
| 25 | + | |
| 26 | +### 请求 /bpm/process-instance/my-page 接口 => 成功 | |
| 27 | +GET {{baseUrl}}/bpm/process-instance/my-page | |
| 28 | +tenant-id: 1 | |
| 29 | +Authorization: Bearer {{token}} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.controller.task; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO; | |
| 3 | 4 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; |
| 5 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; | |
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; | |
| 4 | 7 | import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService; |
| 5 | 8 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 9 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | 10 | import io.swagger.annotations.Api; |
| 7 | 11 | import io.swagger.annotations.ApiOperation; |
| 8 | 12 | import org.springframework.validation.annotation.Validated; |
| 9 | -import org.springframework.web.bind.annotation.PostMapping; | |
| 10 | -import org.springframework.web.bind.annotation.RequestBody; | |
| 11 | -import org.springframework.web.bind.annotation.RequestMapping; | |
| 12 | -import org.springframework.web.bind.annotation.RestController; | |
| 13 | +import org.springframework.web.bind.annotation.*; | |
| 13 | 14 | |
| 14 | 15 | import javax.annotation.Resource; |
| 15 | 16 | import javax.validation.Valid; |
| ... | ... | @@ -26,10 +27,26 @@ public class BpmProcessInstanceController { |
| 26 | 27 | @Resource |
| 27 | 28 | private BpmProcessInstanceService processInstanceService; |
| 28 | 29 | |
| 30 | + // TODO 芋艿:权限 | |
| 31 | + | |
| 29 | 32 | @PostMapping("/create") |
| 30 | 33 | @ApiOperation("新建流程实例") |
| 31 | 34 | public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) { |
| 32 | 35 | return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO)); |
| 33 | 36 | } |
| 34 | 37 | |
| 38 | + @DeleteMapping("/cancel") | |
| 39 | + @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程") | |
| 40 | + public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) { | |
| 41 | + processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO); | |
| 42 | + return success(true); | |
| 43 | + } | |
| 44 | + | |
| 45 | + @GetMapping("/my-page") | |
| 46 | + @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用") | |
| 47 | + public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage( | |
| 48 | + @Valid BpmProcessInstanceMyPageReqVO pageReqVO) { | |
| 49 | + return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO)); | |
| 50 | + } | |
| 51 | + | |
| 35 | 52 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.http
0 → 100644
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/TaskController.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.java
| 1 | -package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow; | |
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.task; | |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.*; | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; | |
| 4 | 4 | import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 6 | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | 7 | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; |
| 8 | 8 | import io.swagger.annotations.Api; |
| 9 | 9 | import io.swagger.annotations.ApiOperation; |
| 10 | +import org.springframework.validation.annotation.Validated; | |
| 10 | 11 | import org.springframework.web.bind.annotation.*; |
| 11 | 12 | |
| 12 | 13 | import javax.annotation.Resource; |
| ... | ... | @@ -16,48 +17,53 @@ import java.io.IOException; |
| 16 | 17 | import java.util.List; |
| 17 | 18 | |
| 18 | 19 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 20 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; | |
| 19 | 21 | |
| 20 | -// TODO @json:swagger 和 validation 的注解,后续要补全下哈。可以等 workflow 基本写的差不多之后 | |
| 21 | -@Api(tags = "工作流待办任务") | |
| 22 | +@Api(tags = "流程任务") | |
| 22 | 23 | @RestController |
| 23 | -@RequestMapping("/workflow/task") | |
| 24 | -public class TaskController { | |
| 24 | +@RequestMapping("/bpm/task") | |
| 25 | +@Validated | |
| 26 | +public class BpmTaskController { | |
| 25 | 27 | |
| 26 | 28 | @Resource |
| 27 | - private BpmTaskService bpmTaskService; | |
| 29 | + private BpmTaskService taskService; | |
| 28 | 30 | |
| 29 | - @GetMapping("/todo/page") | |
| 30 | - @ApiOperation("获取待办任务分页") | |
| 31 | - public CommonResult<PageResult<TodoTaskRespVO>> getTodoTaskPage(@Valid TodoTaskPageReqVO pageVO) { | |
| 32 | - return success(bpmTaskService.getTodoTaskPage(pageVO)); | |
| 33 | - } | |
| 31 | + // TODO 芋艿:权限、validation; | |
| 34 | 32 | |
| 35 | - @GetMapping("/claim") | |
| 36 | - @ApiOperation("签收任务") | |
| 37 | - public CommonResult<Boolean> claimTask(@RequestParam("id") String taskId) { | |
| 38 | - bpmTaskService.claimTask(taskId); | |
| 39 | - return success(true); | |
| 33 | + @GetMapping("todo-page") | |
| 34 | + @ApiOperation("获取 Todo 待办任务分页") | |
| 35 | + public CommonResult<PageResult<BpmTaskTodoPageItemRespVO>> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) { | |
| 36 | + return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO)); | |
| 40 | 37 | } |
| 41 | 38 | |
| 42 | - @PostMapping("/task-steps") | |
| 43 | - public CommonResult<TaskHandleVO> getTaskSteps(@RequestBody TaskQueryReqVO taskQuery) { | |
| 44 | - return success(bpmTaskService.getTaskSteps(taskQuery)); | |
| 39 | + @GetMapping("done-page") | |
| 40 | + @ApiOperation("获取 Done 已办任务分页") | |
| 41 | + public CommonResult<PageResult<BpmTaskDonePageItemRespVO>> getTodoTaskPage(@Valid BpmTaskDonePageReqVO pageVO) { | |
| 42 | + return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO)); | |
| 45 | 43 | } |
| 46 | 44 | |
| 47 | - @PostMapping("/formKey") | |
| 48 | - public CommonResult<TodoTaskRespVO> getTaskFormKey(@RequestBody TaskQueryReqVO taskQuery) { | |
| 49 | - return success(bpmTaskService.getTaskFormKey(taskQuery)); | |
| 45 | + @PutMapping("/approve") | |
| 46 | + @ApiOperation("通过任务") | |
| 47 | + public CommonResult<Boolean> approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) { | |
| 48 | + taskService.approveTask(reqVO); | |
| 49 | + return success(true); | |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | - @PostMapping("/complete") | |
| 53 | - public CommonResult<Boolean> complete(@RequestBody TaskReqVO taskReq) { | |
| 54 | - bpmTaskService.completeTask(taskReq); | |
| 52 | + @PutMapping("/reject") | |
| 53 | + @ApiOperation("不通过任务") | |
| 54 | + public CommonResult<Boolean> rejectTask(@Valid @RequestBody BpmTaskRejectReqVO reqVO) { | |
| 55 | + taskService.rejectTask(reqVO); | |
| 55 | 56 | return success(true); |
| 56 | 57 | } |
| 57 | 58 | |
| 59 | + @PostMapping("/task-steps") | |
| 60 | + public CommonResult<TaskHandleVO> getTaskSteps(@RequestBody TaskQueryReqVO taskQuery) { | |
| 61 | + return success(taskService.getTaskSteps(taskQuery)); | |
| 62 | + } | |
| 63 | + | |
| 58 | 64 | @GetMapping("/process/history-steps") |
| 59 | 65 | public CommonResult<List<TaskStepVO>> getHistorySteps(@RequestParam("id") String processInstanceId) { |
| 60 | - return success(bpmTaskService.getHistorySteps(processInstanceId)); | |
| 66 | + return success(taskService.getHistorySteps(processInstanceId)); | |
| 61 | 67 | } |
| 62 | 68 | |
| 63 | 69 | /** |
| ... | ... | @@ -66,7 +72,7 @@ public class TaskController { |
| 66 | 72 | */ |
| 67 | 73 | @GetMapping("/process/highlight-img") |
| 68 | 74 | public void getHighlightImg(@RequestParam String processInstanceId, HttpServletResponse response) throws IOException { |
| 69 | - FileResp fileResp = bpmTaskService.getHighlightImg(processInstanceId); | |
| 75 | + FileResp fileResp = taskService.getHighlightImg(processInstanceId); | |
| 70 | 76 | ServletUtils.writeAttachment(response, fileResp.getFileName(), fileResp.getFileByte()); |
| 71 | 77 | } |
| 72 | 78 | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceCancelReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.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-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceCreateReqVO.java
| ... | ... | @@ -9,8 +9,6 @@ import java.util.Map; |
| 9 | 9 | |
| 10 | 10 | @ApiModel("流程实例的创建 Request VO") |
| 11 | 11 | @Data |
| 12 | -//@EqualsAndHashCode(callSuper = true) | |
| 13 | -//@ToString(callSuper = true) | |
| 14 | 12 | public class BpmProcessInstanceCreateReqVO { |
| 15 | 13 | |
| 16 | 14 | @ApiModelProperty(value = "流程定义的编号", required = true, example = "1024") | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceMyPageReqVO.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance; |
| 2 | 2 | |
| 3 | 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; | |
| 4 | 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) | |
| 5 | 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 | + | |
| 6 | 44 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstancePageItemRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.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-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskApproveReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.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-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskDonePageItemRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.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("流程任务的 Done 已完成的分页项 Response VO") | |
| 10 | +@Data | |
| 11 | +public class BpmTaskDonePageItemRespVO { | |
| 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 | + @ApiModelProperty(value = "结束时间", required = true) | |
| 25 | + private Date endTime; | |
| 26 | + @ApiModelProperty(value = "持续时间", required = true, example = "1000") | |
| 27 | + private Long durationInMillis; | |
| 28 | + | |
| 29 | + @ApiModelProperty(value = "任务结果", required = true, notes = "参见 bpm_process_instance_result", example = "2") | |
| 30 | + private Integer result; | |
| 31 | + @ApiModelProperty(value = "审批建议", required = true, example = "不请假了!") | |
| 32 | + private String comment; | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * 所属流程实例 | |
| 36 | + */ | |
| 37 | + private ProcessInstance processInstance; | |
| 38 | + | |
| 39 | + @Data | |
| 40 | + @ApiModel("流程实例") | |
| 41 | + public static class ProcessInstance { | |
| 42 | + | |
| 43 | + @ApiModelProperty(value = "流程实例编号", required = true, example = "1024") | |
| 44 | + private String id; | |
| 45 | + | |
| 46 | + @ApiModelProperty(value = "流程实例名称", required = true, example = "芋道") | |
| 47 | + private String name; | |
| 48 | + | |
| 49 | + @ApiModelProperty(value = "发起人的用户编号", required = true, example = "1024") | |
| 50 | + private Long startUserId; | |
| 51 | + | |
| 52 | + @ApiModelProperty(value = "发起人的用户昵称", required = true, example = "芋艿") | |
| 53 | + private String startUserNickname; | |
| 54 | + | |
| 55 | + @ApiModelProperty(value = "流程定义的编号", required = true, example = "2048") | |
| 56 | + private String processDefinitionId; | |
| 57 | + | |
| 58 | + } | |
| 59 | + | |
| 60 | + | |
| 61 | + // 任务编号、流程名称、任务节点、流程发起人、接收时间、审批时间、耗时【名称、开始时间】「流程记录、撤回」 | |
| 62 | + // 任务编号、任务名称、所属流程、委托代办人、流程发起人、优先级、审批操作、审批意见、耗时、创建时间【名称、开始时间】「申请详情」 | |
| 63 | + | |
| 64 | + // 任务编号、任务名称、流程名称、流程发起人、接收时间、审批时间、耗时【名称、接收时间】「详情」TODO 撤回 | |
| 65 | + | |
| 66 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskDonePageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.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-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskRejectReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.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-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageItemRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.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-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.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-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/FileResp.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/FileResp.java
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskHandleVO.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TaskHandleVO.java
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskQueryReqVO.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TaskQueryReqVO.java
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskStepVO.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TaskStepVO.java
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskReqVO.java deleted
| 1 | -package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo; | |
| 2 | - | |
| 3 | -import lombok.Data; | |
| 4 | -import lombok.ToString; | |
| 5 | - | |
| 6 | -import java.util.Map; | |
| 7 | - | |
| 8 | -@Data | |
| 9 | -@ToString | |
| 10 | -public class TaskReqVO { | |
| 11 | - | |
| 12 | - private String taskId; | |
| 13 | - | |
| 14 | - private Map<String,Object> variables; | |
| 15 | - | |
| 16 | - private String comment; | |
| 17 | -} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TodoTaskRespVO.java deleted
| 1 | -package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo; | |
| 2 | - | |
| 3 | -import io.swagger.annotations.ApiModel; | |
| 4 | -import lombok.Data; | |
| 5 | -import lombok.ToString; | |
| 6 | - | |
| 7 | -@ApiModel("待办任务 Response VO") | |
| 8 | -@Data | |
| 9 | -@ToString | |
| 10 | -public class TodoTaskRespVO { | |
| 11 | - | |
| 12 | - // TODO @jason:swagger 注解。这样接口文档才完整哈 | |
| 13 | - | |
| 14 | - private String id; | |
| 15 | - | |
| 16 | - | |
| 17 | - private String processInstanceId; | |
| 18 | - | |
| 19 | - /** | |
| 20 | - * 1:未签收 | |
| 21 | - * 2:已签收 | |
| 22 | - */ | |
| 23 | - private Integer status; | |
| 24 | - | |
| 25 | - | |
| 26 | - private String processName; | |
| 27 | - | |
| 28 | - | |
| 29 | - private String processKey; | |
| 30 | - | |
| 31 | - | |
| 32 | - private String businessKey; | |
| 33 | - | |
| 34 | - | |
| 35 | - private String formKey; | |
| 36 | - | |
| 37 | -} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmDefinitionConvert.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO; |
| 4 | -import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionDO; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionRespVO; | |
| 5 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; | |
| 5 | 6 | import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO; |
| 6 | 7 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; |
| 7 | 8 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| ... | ... | @@ -9,10 +10,14 @@ import org.activiti.engine.impl.persistence.entity.SuspensionState; |
| 9 | 10 | import org.activiti.engine.repository.Deployment; |
| 10 | 11 | import org.activiti.engine.repository.ProcessDefinition; |
| 11 | 12 | import org.mapstruct.Mapper; |
| 13 | +import org.mapstruct.Mapping; | |
| 14 | +import org.mapstruct.Mappings; | |
| 15 | +import org.mapstruct.Named; | |
| 12 | 16 | import org.mapstruct.factory.Mappers; |
| 13 | 17 | |
| 14 | 18 | import java.util.List; |
| 15 | 19 | import java.util.Map; |
| 20 | +import java.util.function.Function; | |
| 16 | 21 | |
| 17 | 22 | /** |
| 18 | 23 | * Bpm 流程定义的 Convert |
| ... | ... | @@ -25,17 +30,17 @@ public interface BpmDefinitionConvert { |
| 25 | 30 | BpmDefinitionConvert INSTANCE = Mappers.getMapper(BpmDefinitionConvert.class); |
| 26 | 31 | |
| 27 | 32 | default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap, |
| 28 | - Map<String, BpmProcessDefinitionDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) { | |
| 33 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) { | |
| 29 | 34 | return CollectionUtils.convertList(list, definition -> { |
| 30 | 35 | Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null; |
| 31 | - BpmProcessDefinitionDO definitionDO = processDefinitionDOMap.get(definition.getId()); | |
| 36 | + BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId()); | |
| 32 | 37 | BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null; |
| 33 | 38 | return convert(definition, deployment, definitionDO, form); |
| 34 | 39 | }); |
| 35 | 40 | } |
| 36 | 41 | |
| 37 | 42 | default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment, |
| 38 | - BpmProcessDefinitionDO processDefinitionDO, BpmFormDO form) { | |
| 43 | + BpmProcessDefinitionExtDO processDefinitionDO, BpmFormDO form) { | |
| 39 | 44 | BpmProcessDefinitionPageItemRespVO respVO = convert(bean); |
| 40 | 45 | respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode()); |
| 41 | 46 | if (deployment != null) { |
| ... | ... | @@ -53,6 +58,27 @@ public interface BpmDefinitionConvert { |
| 53 | 58 | |
| 54 | 59 | BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean); |
| 55 | 60 | |
| 56 | - BpmProcessDefinitionDO convert2(BpmDefinitionCreateReqDTO bean); | |
| 61 | + BpmProcessDefinitionExtDO convert2(BpmDefinitionCreateReqDTO bean); | |
| 62 | + | |
| 63 | + default List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list, | |
| 64 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap) { | |
| 65 | + return CollectionUtils.convertList(list, processDefinition -> { | |
| 66 | + BpmProcessDefinitionRespVO respVO = convert3(processDefinition); | |
| 67 | + BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId()); | |
| 68 | + if (processDefinitionExtDO != null) { | |
| 69 | + respVO.setFormId(processDefinitionExtDO.getFormId()); | |
| 70 | + } | |
| 71 | + return respVO; | |
| 72 | + }); | |
| 73 | + } | |
| 74 | + | |
| 75 | + @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState") | |
| 76 | + BpmProcessDefinitionRespVO convert3(ProcessDefinition bean); | |
| 77 | + | |
| 78 | + @Named("convertSuspendedToSuspensionState") | |
| 79 | + default Integer convertSuspendedToSuspensionState(boolean suspended) { | |
| 80 | + return suspended ? SuspensionState.SUSPENDED.getStateCode() : | |
| 81 | + SuspensionState.ACTIVE.getStateCode(); | |
| 82 | + } | |
| 57 | 83 | |
| 58 | 84 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmProcessInstanceConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.convert.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import org.activiti.engine.repository.ProcessDefinition; | |
| 7 | +import org.activiti.engine.runtime.ProcessInstance; | |
| 8 | +import org.activiti.engine.task.Task; | |
| 9 | +import org.mapstruct.Mapper; | |
| 10 | +import org.mapstruct.Mapping; | |
| 11 | +import org.mapstruct.Mappings; | |
| 12 | +import org.mapstruct.factory.Mappers; | |
| 13 | + | |
| 14 | +import java.sql.SQLXML; | |
| 15 | +import java.util.List; | |
| 16 | +import java.util.Map; | |
| 17 | +import java.util.function.Consumer; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * 流程实例 Convert | |
| 21 | + * | |
| 22 | + * @author 芋道源码 | |
| 23 | + */ | |
| 24 | +@Mapper | |
| 25 | +public interface BpmProcessInstanceConvert { | |
| 26 | + | |
| 27 | + BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class); | |
| 28 | + | |
| 29 | + @Mappings({ | |
| 30 | + @Mapping(source = "instance.startUserId", target = "startUserId"), | |
| 31 | + @Mapping(source = "instance.id", target = "processInstanceId"), | |
| 32 | + @Mapping(source = "instance.startTime", target = "createTime"), | |
| 33 | + @Mapping(source = "definition.id", target = "processDefinitionId"), | |
| 34 | + @Mapping(source = "definition.name", target = "name"), | |
| 35 | + @Mapping(source = "definition.category", target = "category") | |
| 36 | + }) | |
| 37 | + BpmProcessInstanceExtDO convert(ProcessInstance instance, ProcessDefinition definition); | |
| 38 | + | |
| 39 | + default PageResult<BpmProcessInstancePageItemRespVO> convertPage(PageResult<BpmProcessInstanceExtDO> page, | |
| 40 | + Map<String, List<Task>> taskMap) { | |
| 41 | + List<BpmProcessInstancePageItemRespVO> list = convertList(page.getList()); | |
| 42 | + list.forEach(respVO -> respVO.setTasks(convertList2(taskMap.get(respVO.getId())))); | |
| 43 | + return new PageResult<>(list, page.getTotal()); | |
| 44 | + } | |
| 45 | + | |
| 46 | + List<BpmProcessInstancePageItemRespVO> convertList(List<BpmProcessInstanceExtDO> list); | |
| 47 | + | |
| 48 | + List<BpmProcessInstancePageItemRespVO.Task> convertList2(List<Task> tasks); | |
| 49 | + | |
| 50 | + @Mapping(source = "processInstanceId", target = "id") | |
| 51 | + BpmProcessInstancePageItemRespVO convert(BpmProcessInstanceExtDO bean); | |
| 52 | + | |
| 53 | + @Mappings({ | |
| 54 | + @Mapping(source = "id", target = "processInstanceId"), | |
| 55 | + @Mapping(source = "startDate", target = "createTime"), | |
| 56 | + @Mapping(source = "initiator", target = "startUserId"), | |
| 57 | + @Mapping(source = "status", target = "status", ignore = true) | |
| 58 | + }) | |
| 59 | + BpmProcessInstanceExtDO convert(org.activiti.api.process.model.ProcessInstance bean); | |
| 60 | + | |
| 61 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmTaskConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.convert.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskDonePageItemRespVO; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskTodoPageItemRespVO; | |
| 5 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.TaskStepVO; | |
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO; | |
| 7 | +import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; | |
| 8 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 9 | +import org.activiti.engine.history.HistoricActivityInstance; | |
| 10 | +import org.activiti.engine.history.HistoricProcessInstance; | |
| 11 | +import org.activiti.engine.history.HistoricTaskInstance; | |
| 12 | +import org.activiti.engine.impl.persistence.entity.SuspensionState; | |
| 13 | +import org.activiti.engine.runtime.ProcessInstance; | |
| 14 | +import org.activiti.engine.task.Task; | |
| 15 | +import org.mapstruct.Mapper; | |
| 16 | +import org.mapstruct.Mapping; | |
| 17 | +import org.mapstruct.Mappings; | |
| 18 | +import org.mapstruct.Named; | |
| 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 | + @Mappings(value = { | |
| 35 | + @Mapping(source = "activityName", target = "stepName"), | |
| 36 | + @Mapping(source = "assignee", target = "assignee") | |
| 37 | + }) | |
| 38 | + TaskStepVO convert(HistoricActivityInstance instance); | |
| 39 | + | |
| 40 | + default List<BpmTaskTodoPageItemRespVO> convertList(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap, | |
| 41 | + Map<Long, SysUserDO> userMap) { | |
| 42 | + return CollectionUtils.convertList(tasks, task -> { | |
| 43 | + ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId()); | |
| 44 | + return convert(task, processInstance, userMap.get(Long.valueOf(processInstance.getStartUserId()))); | |
| 45 | + }); | |
| 46 | + } | |
| 47 | + | |
| 48 | + @Mappings({ | |
| 49 | + @Mapping(source = "task.id", target = "id"), | |
| 50 | + @Mapping(source = "task.name", target = "name"), | |
| 51 | + @Mapping(source = "task.claimTime", target = "claimTime"), | |
| 52 | + @Mapping(source = "task.createTime", target = "createTime"), | |
| 53 | + @Mapping(source = "task.suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState"), | |
| 54 | + @Mapping(source = "processInstance.id", target = "processInstance.id"), | |
| 55 | + @Mapping(source = "processInstance.name", target = "processInstance.name"), | |
| 56 | + @Mapping(source = "processInstance.startUserId", target = "processInstance.startUserId"), | |
| 57 | + @Mapping(source = "processInstance.processDefinitionId", target = "processInstance.processDefinitionId"), | |
| 58 | + @Mapping(source = "user.nickname", target = "processInstance.startUserNickname") | |
| 59 | + }) | |
| 60 | + BpmTaskTodoPageItemRespVO convert(Task task, ProcessInstance processInstance, SysUserDO user); | |
| 61 | + | |
| 62 | + @Named("convertSuspendedToSuspensionState") | |
| 63 | + default Integer convertSuspendedToSuspensionState(boolean suspended) { | |
| 64 | + return suspended ? SuspensionState.SUSPENDED.getStateCode() : | |
| 65 | + SuspensionState.ACTIVE.getStateCode(); | |
| 66 | + } | |
| 67 | + | |
| 68 | + default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap, | |
| 69 | + Map<String, HistoricProcessInstance> historicProcessInstanceMap, | |
| 70 | + Map<Long, SysUserDO> userMap) { | |
| 71 | + return CollectionUtils.convertList(tasks, task -> { | |
| 72 | + BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId()); | |
| 73 | + HistoricProcessInstance processInstance = historicProcessInstanceMap.get(task.getProcessInstanceId()); | |
| 74 | + SysUserDO userDO = userMap.get(Long.valueOf(processInstance.getStartUserId())); | |
| 75 | + return convert(task, taskExtDO, processInstance, userDO); | |
| 76 | + }); | |
| 77 | + } | |
| 78 | + | |
| 79 | + @Mappings({ | |
| 80 | + @Mapping(source = "task.id", target = "id"), | |
| 81 | + @Mapping(source = "task.name", target = "name"), | |
| 82 | + @Mapping(source = "task.claimTime", target = "claimTime"), | |
| 83 | + @Mapping(source = "task.createTime", target = "createTime"), | |
| 84 | + @Mapping(source = "task.endTime", target = "endTime"), | |
| 85 | + @Mapping(source = "task.durationInMillis", target = "durationInMillis"), | |
| 86 | + @Mapping(source = "taskExtDO.result", target = "result"), | |
| 87 | + @Mapping(source = "taskExtDO.comment", target = "comment"), | |
| 88 | + @Mapping(source = "processInstance.id", target = "processInstance.id"), | |
| 89 | + @Mapping(source = "processInstance.name", target = "processInstance.name"), | |
| 90 | + @Mapping(source = "processInstance.startUserId", target = "processInstance.startUserId"), | |
| 91 | + @Mapping(source = "processInstance.processDefinitionId", target = "processInstance.processDefinitionId"), | |
| 92 | + @Mapping(source = "user.nickname", target = "processInstance.startUserNickname") | |
| 93 | + }) | |
| 94 | + BpmTaskDonePageItemRespVO convert(HistoricTaskInstance task, BpmTaskExtDO taskExtDO, HistoricProcessInstance processInstance, SysUserDO user); | |
| 95 | + | |
| 96 | + @Mappings({ | |
| 97 | + @Mapping(source = "id", target = "taskId"), | |
| 98 | + @Mapping(source = "assignee", target = "assigneeUserId"), | |
| 99 | + @Mapping(source = "createdDate", target = "createTime") | |
| 100 | + }) | |
| 101 | + BpmTaskExtDO convert(org.activiti.api.task.model.Task bean); | |
| 102 | + | |
| 103 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/workflow/TaskConvert.java deleted
| 1 | -package cn.iocoder.yudao.adminserver.modules.bpm.convert.workflow; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.TaskStepVO; | |
| 4 | -import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.TodoTaskRespVO; | |
| 5 | -import org.activiti.api.task.model.Task; | |
| 6 | -import org.activiti.engine.history.HistoricActivityInstance; | |
| 7 | -import org.activiti.engine.repository.ProcessDefinition; | |
| 8 | -import org.mapstruct.Mapper; | |
| 9 | -import org.mapstruct.Mapping; | |
| 10 | -import org.mapstruct.Mappings; | |
| 11 | -import org.mapstruct.Named; | |
| 12 | -import org.mapstruct.factory.Mappers; | |
| 13 | - | |
| 14 | -@Mapper | |
| 15 | -public interface TaskConvert { | |
| 16 | - TaskConvert INSTANCE = Mappers.getMapper(TaskConvert.class); | |
| 17 | - | |
| 18 | - @Mappings(value = { | |
| 19 | - @Mapping(source = "task.id", target = "id"), | |
| 20 | - @Mapping(source = "task.businessKey", target = "businessKey"), | |
| 21 | - @Mapping(source = "task.assignee", target = "status",qualifiedByName = "convertAssigneeToStatus"), | |
| 22 | - @Mapping(source = "definition.name", target = "processName"), | |
| 23 | - @Mapping(source = "definition.key", target = "processKey"), | |
| 24 | - @Mapping(source = "definition.id", target = "processInstanceId") | |
| 25 | - }) | |
| 26 | - TodoTaskRespVO convert(Task task, ProcessDefinition definition); | |
| 27 | - | |
| 28 | - @Mappings(value = { | |
| 29 | - @Mapping(source = "assignee", target = "status",qualifiedByName = "convertAssigneeToStatus") | |
| 30 | - }) | |
| 31 | - TodoTaskRespVO convert(Task task); | |
| 32 | - | |
| 33 | - @Named("convertAssigneeToStatus") | |
| 34 | - default Integer convertAssigneeToStatus(String assignee) { | |
| 35 | - //TODO 不应该通过 assignee 定义状态 需要定义更多的状态 | |
| 36 | - return assignee == null ? 1 : 2; | |
| 37 | - } | |
| 38 | - | |
| 39 | - @Mappings(value = { | |
| 40 | - @Mapping(source = "activityName", target = "stepName"), | |
| 41 | - @Mapping(source = "assignee", target = "assignee") | |
| 42 | - }) | |
| 43 | - TaskStepVO convert(HistoricActivityInstance instance); | |
| 44 | -} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/definition/BpmProcessDefinitionDO.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java
| ... | ... | @@ -9,18 +9,18 @@ import org.activiti.engine.repository.ProcessDefinition; |
| 9 | 9 | |
| 10 | 10 | /** |
| 11 | 11 | * Bpm 流程定义的拓展表 |
| 12 | - * 主要解决 主要进行 Activiti {@link ProcessDefinition} 不支持拓展字段,所以新建拓展表 | |
| 12 | + * 主要解决 Activiti {@link ProcessDefinition} 不支持拓展字段,所以新建拓展表 | |
| 13 | 13 | * |
| 14 | 14 | * @author 芋道源码 |
| 15 | 15 | */ |
| 16 | -@TableName(value = "bpm_process_definition", autoResultMap = true) | |
| 16 | +@TableName(value = "bpm_process_definition_ext", autoResultMap = true) | |
| 17 | 17 | @Data |
| 18 | 18 | @EqualsAndHashCode(callSuper = true) |
| 19 | 19 | @ToString(callSuper = true) |
| 20 | 20 | @Builder |
| 21 | 21 | @NoArgsConstructor |
| 22 | 22 | @AllArgsConstructor |
| 23 | -public class BpmProcessDefinitionDO extends BaseDO { | |
| 23 | +public class BpmProcessDefinitionExtDO extends BaseDO { | |
| 24 | 24 | |
| 25 | 25 | /** |
| 26 | 26 | * 编号 | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceStatusEnum; | |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 6 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 7 | +import lombok.Data; | |
| 8 | +import lombok.EqualsAndHashCode; | |
| 9 | +import lombok.ToString; | |
| 10 | +import org.activiti.engine.history.HistoricProcessInstance; | |
| 11 | +import org.activiti.engine.repository.ProcessDefinition; | |
| 12 | +import org.activiti.engine.runtime.ProcessInstance; | |
| 13 | + | |
| 14 | +import java.util.Date; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * Bpm 流程实例的拓展表 | |
| 18 | + * 主要解决 Activiti {@link ProcessInstance} 和 {@link HistoricProcessInstance} 不支持拓展字段,所以新建拓展表 | |
| 19 | + * | |
| 20 | + * @author 芋道源码 | |
| 21 | + */ | |
| 22 | +@TableName(value = "bpm_process_instance_ext", autoResultMap = true) | |
| 23 | +@Data | |
| 24 | +@EqualsAndHashCode(callSuper = true) | |
| 25 | +@ToString(callSuper = true) | |
| 26 | +//@Builder | |
| 27 | +//@NoArgsConstructor | |
| 28 | +//@AllArgsConstructor | |
| 29 | +public class BpmProcessInstanceExtDO extends BaseDO { | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * 发起流程的用户编号 | |
| 33 | + * | |
| 34 | + * 冗余 {@link HistoricProcessInstance#getStartUserId()} | |
| 35 | + */ | |
| 36 | + private Long startUserId; | |
| 37 | + /** | |
| 38 | + * 流程实例的名字 | |
| 39 | + * | |
| 40 | + * 冗余 {@link ProcessInstance#getName()} 为了筛选 | |
| 41 | + */ | |
| 42 | + private String name; | |
| 43 | + /** | |
| 44 | + * 流程实例的编号 | |
| 45 | + * | |
| 46 | + * 关联 {@link ProcessInstance#getId()} | |
| 47 | + */ | |
| 48 | + private String processInstanceId; | |
| 49 | + /** | |
| 50 | + * 流程定义的编号 | |
| 51 | + * | |
| 52 | + * 关联 {@link ProcessDefinition#getId()} | |
| 53 | + */ | |
| 54 | + private String processDefinitionId; | |
| 55 | + /** | |
| 56 | + * 流程分类 | |
| 57 | + * | |
| 58 | + * 冗余 {@link ProcessDefinition#getCategory()} | |
| 59 | + * 数据字典 bpm_model_category | |
| 60 | + */ | |
| 61 | + private String category; | |
| 62 | + /** | |
| 63 | + * 流程实例的状态 | |
| 64 | + * | |
| 65 | + * 枚举 {@link BpmProcessInstanceStatusEnum} | |
| 66 | + */ | |
| 67 | + private Integer status; | |
| 68 | + /** | |
| 69 | + * 流程实例的结果 | |
| 70 | + * | |
| 71 | + * 枚举 {@link BpmProcessInstanceResultEnum} | |
| 72 | + */ | |
| 73 | + private Integer result; | |
| 74 | + /** | |
| 75 | + * 结束时间 | |
| 76 | + * | |
| 77 | + * 冗余 {@link HistoricProcessInstance#getEndTime()} | |
| 78 | + */ | |
| 79 | + private Date endTime; | |
| 80 | + | |
| 81 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmTaskExtDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 5 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.EqualsAndHashCode; | |
| 8 | +import lombok.ToString; | |
| 9 | +import org.activiti.engine.history.HistoricTaskInstance; | |
| 10 | +import org.activiti.engine.repository.ProcessDefinition; | |
| 11 | +import org.activiti.engine.runtime.ProcessInstance; | |
| 12 | +import org.activiti.engine.task.Task; | |
| 13 | + | |
| 14 | +import java.util.Date; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * Bpm 流程任务的拓展表 | |
| 18 | + * 主要解决 Activiti {@link Task} 和 {@link HistoricTaskInstance} 不支持拓展字段,所以新建拓展表 | |
| 19 | + * | |
| 20 | + * @author 芋道源码 | |
| 21 | + */ | |
| 22 | +@TableName(value = "bpm_task_ext", autoResultMap = true) | |
| 23 | +@Data | |
| 24 | +@EqualsAndHashCode(callSuper = true) | |
| 25 | +@ToString(callSuper = true) | |
| 26 | +//@Builder | |
| 27 | +//@NoArgsConstructor | |
| 28 | +//@AllArgsConstructor | |
| 29 | +public class BpmTaskExtDO extends BaseDO { | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * 任务的审批人 | |
| 33 | + * | |
| 34 | + * 冗余 {@link Task#getAssignee()} | |
| 35 | + */ | |
| 36 | + private Long assigneeUserId; | |
| 37 | + /** | |
| 38 | + * 任务的名字 | |
| 39 | + * | |
| 40 | + * 冗余 {@link Task#getName()} 为了筛选 | |
| 41 | + */ | |
| 42 | + private String name; | |
| 43 | + /** | |
| 44 | + * 任务的编号 | |
| 45 | + * | |
| 46 | + * 关联 {@link Task#getId()} | |
| 47 | + */ | |
| 48 | + private String taskId; | |
| 49 | + /** | |
| 50 | + * 任务的结果 | |
| 51 | + * | |
| 52 | + * 枚举 {@link BpmProcessInstanceResultEnum} | |
| 53 | + */ | |
| 54 | + private Integer result; | |
| 55 | + /** | |
| 56 | + * 审批建议 | |
| 57 | + */ | |
| 58 | + private String comment; | |
| 59 | + /** | |
| 60 | + * 任务的结束时间 | |
| 61 | + * | |
| 62 | + * 冗余 {@link HistoricTaskInstance#getEndTime()} | |
| 63 | + */ | |
| 64 | + private Date endTime; | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * 流程实例的编号 | |
| 68 | + * | |
| 69 | + * 关联 {@link ProcessInstance#getId()} | |
| 70 | + */ | |
| 71 | + private String processInstanceId; | |
| 72 | + /** | |
| 73 | + * 流程定义的编号 | |
| 74 | + * | |
| 75 | + * 关联 {@link ProcessDefinition#getId()} | |
| 76 | + */ | |
| 77 | + private String processDefinitionId; | |
| 78 | + | |
| 79 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/package-info.java deleted
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/definition/BpmProcessDefinitionMapper.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/definition/BpmProcessDefinitionExtMapper.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionDO; | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; | |
| 4 | 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| 5 | 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| 6 | 6 | import org.apache.ibatis.annotations.Mapper; |
| ... | ... | @@ -9,10 +9,10 @@ import java.util.Collection; |
| 9 | 9 | import java.util.List; |
| 10 | 10 | |
| 11 | 11 | @Mapper |
| 12 | -public interface BpmProcessDefinitionMapper extends BaseMapper<BpmProcessDefinitionDO> { | |
| 12 | +public interface BpmProcessDefinitionExtMapper extends BaseMapper<BpmProcessDefinitionExtDO> { | |
| 13 | 13 | |
| 14 | - default List<BpmProcessDefinitionDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) { | |
| 15 | - return selectList(new QueryWrapper<BpmProcessDefinitionDO>().in("process_definition_id", processDefinitionIds)); | |
| 14 | + default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) { | |
| 15 | + return selectList(new QueryWrapper<BpmProcessDefinitionExtDO>().in("process_definition_id", processDefinitionIds)); | |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | 18 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.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 void updateByProcessInstanceId(BpmProcessInstanceExtDO updateObj) { | |
| 27 | + update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>() | |
| 28 | + .eq("process_instance_id", updateObj.getProcessInstanceId())); | |
| 29 | + } | |
| 30 | + | |
| 31 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmTaskExtMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO; | |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 5 | +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |
| 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 QueryWrapper<BpmTaskExtDO>().eq("task_id", entity.getTaskId())); | |
| 16 | + } | |
| 17 | + | |
| 18 | + default List<BpmTaskExtDO> selectListByTaskIds(Collection<String> taskIds) { | |
| 19 | + return selectList("task_id", taskIds); | |
| 20 | + } | |
| 21 | + | |
| 22 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java
| ... | ... | @@ -10,7 +10,6 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; |
| 10 | 10 | public interface BpmErrorCodeConstants { |
| 11 | 11 | |
| 12 | 12 | // ========== 通用流程处理 模块 1-009-000-000 ========== |
| 13 | - ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009000001, "流程实例不存在"); | |
| 14 | 13 | ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常"); |
| 15 | 14 | |
| 16 | 15 | // ========== OA 流程模块 1-009-001-000 ========== |
| ... | ... | @@ -34,7 +33,12 @@ public interface BpmErrorCodeConstants { |
| 34 | 33 | ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003002, "流程定义处于挂起状态"); |
| 35 | 34 | |
| 36 | 35 | // ========== 流程实例 1-009-004-000 ========== |
| 36 | + ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009004000, "流程实例不存在"); | |
| 37 | + ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004001, "流程取消失败,流程不处于运行中"); | |
| 38 | + ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1009004002, "流程取消失败,该流程不是你发起的"); | |
| 37 | 39 | |
| 40 | + // ========== 流程实例 1-009-005-000 ========== | |
| 41 | + ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "审批任务失败,原因:该任务不处于未审批"); | |
| 38 | 42 | |
| 39 | 43 | // ========== 动态表单模块 1-009-010-000 ========== |
| 40 | 44 | ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在"); | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.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 BpmProcessInstanceDeleteReasonEnum { | |
| 14 | + | |
| 15 | + REJECT_TASK("驳回任务"); | |
| 16 | + | |
| 17 | + private final String reason; | |
| 18 | + | |
| 19 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/BpmProcessInstanceResultEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.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-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/FlowStatusEnum.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/BpmProcessInstanceStatusEnum.java
| 1 | -package cn.iocoder.yudao.adminserver.modules.bpm.enums; | |
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.enums.task; | |
| 2 | 2 | |
| 3 | 3 | import lombok.AllArgsConstructor; |
| 4 | 4 | import lombok.Getter; |
| 5 | 5 | |
| 6 | 6 | /** |
| 7 | - * 流程状态 | |
| 7 | + * 流程实例的状态 | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 8 | 10 | */ |
| 9 | 11 | @Getter |
| 10 | 12 | @AllArgsConstructor |
| 11 | -public enum FlowStatusEnum { | |
| 13 | +public enum BpmProcessInstanceStatusEnum { | |
| 12 | 14 | |
| 13 | - HANDLE(1, "处理中"), | |
| 14 | - | |
| 15 | - PASS(2, "审批通过"), | |
| 16 | - | |
| 17 | - REJECTED(3, "审批不通过"); | |
| 15 | + RUNNING(1, "进行中"), | |
| 16 | + FINISH(2, "已完成"); | |
| 18 | 17 | |
| 19 | 18 | /** |
| 20 | 19 | * 状态 |
| 21 | 20 | */ |
| 22 | 21 | private final Integer status; |
| 23 | - | |
| 24 | - | |
| 25 | 22 | /** |
| 26 | 23 | * 描述 |
| 27 | 24 | */ |
| 28 | 25 | private final String desc; |
| 26 | + | |
| 29 | 27 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/BpmActivitiConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener.BpmTackActivitiEventListener; | |
| 4 | +import org.activiti.spring.SpringProcessEngineConfiguration; | |
| 5 | +import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer; | |
| 6 | +import org.springframework.context.annotation.Configuration; | |
| 7 | + | |
| 8 | +import javax.annotation.Resource; | |
| 9 | +import java.util.Collections; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * BPM 模块的 Activiti 配置类 | |
| 13 | + */ | |
| 14 | +@Configuration | |
| 15 | +public class BpmActivitiConfiguration implements ProcessEngineConfigurationConfigurer { | |
| 16 | + | |
| 17 | + @Resource | |
| 18 | + private BpmTackActivitiEventListener taskActivitiEventListener; | |
| 19 | + | |
| 20 | + @Override | |
| 21 | + public void configure(SpringProcessEngineConfiguration configuration) { | |
| 22 | + // 注册监听器,例如说 BpmActivitiEventListener | |
| 23 | + configuration.setEventListeners(Collections.singletonList(taskActivitiEventListener)); | |
| 24 | + } | |
| 25 | + | |
| 26 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/package-info.java
0 → 100644
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmProcessDefinitionService.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.service.definition; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionListReqVO; | |
| 3 | 4 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO; |
| 4 | 5 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageReqVO; |
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionRespVO; | |
| 5 | 7 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; |
| 6 | 8 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | 9 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| ... | ... | @@ -31,6 +33,14 @@ public interface BpmProcessDefinitionService { |
| 31 | 33 | PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO); |
| 32 | 34 | |
| 33 | 35 | /** |
| 36 | + * 获得流程定义列表 | |
| 37 | + * | |
| 38 | + * @param listReqVO 列表入参 | |
| 39 | + * @return 流程定义列表 | |
| 40 | + */ | |
| 41 | + List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO); | |
| 42 | + | |
| 43 | + /** | |
| 34 | 44 | * 获得流程定义对应的 BPMN XML |
| 35 | 45 | * |
| 36 | 46 | * @param id 流程定义编号 |
| ... | ... | @@ -55,6 +65,16 @@ public interface BpmProcessDefinitionService { |
| 55 | 65 | ProcessDefinition getProcessDefinition(String id); |
| 56 | 66 | |
| 57 | 67 | /** |
| 68 | + * 获得编号对应的 ProcessDefinition | |
| 69 | + * | |
| 70 | + * 相比 {@link #getProcessDefinition(String)} 方法,category 的取值是正确 | |
| 71 | + * | |
| 72 | + * @param id 编号 | |
| 73 | + * @return 流程定义 | |
| 74 | + */ | |
| 75 | + ProcessDefinition getProcessDefinition2(String id); | |
| 76 | + | |
| 77 | + /** | |
| 58 | 78 | * 获得 id 对应的 Deployment |
| 59 | 79 | * |
| 60 | 80 | * @param id 部署编号 | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java
| ... | ... | @@ -2,12 +2,14 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionListReqVO; | |
| 5 | 6 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO; |
| 6 | 7 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageReqVO; |
| 8 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionRespVO; | |
| 7 | 9 | import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmDefinitionConvert; |
| 8 | -import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionDO; | |
| 10 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; | |
| 9 | 11 | import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO; |
| 10 | -import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmProcessDefinitionMapper; | |
| 12 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; | |
| 11 | 13 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; |
| 12 | 14 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; |
| 13 | 15 | import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService; |
| ... | ... | @@ -56,7 +58,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ |
| 56 | 58 | private BpmFormService bpmFormService; |
| 57 | 59 | |
| 58 | 60 | @Resource |
| 59 | - private BpmProcessDefinitionMapper processDefinitionMapper; | |
| 61 | + private BpmProcessDefinitionExtMapper processDefinitionMapper; | |
| 60 | 62 | |
| 61 | 63 | @Override |
| 62 | 64 | public PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) { |
| ... | ... | @@ -77,14 +79,13 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ |
| 77 | 79 | Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds); |
| 78 | 80 | |
| 79 | 81 | // 获得 BpmProcessDefinitionDO Map |
| 80 | - List<BpmProcessDefinitionDO> processDefinitionDOs = Collections.emptyList(); | |
| 81 | - processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds( | |
| 82 | + List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds( | |
| 82 | 83 | convertList(processDefinitions, ProcessDefinition::getId)); |
| 83 | - Map<String, BpmProcessDefinitionDO> processDefinitionDOMap = CollectionUtils.convertMap(processDefinitionDOs, | |
| 84 | - BpmProcessDefinitionDO::getProcessDefinitionId); | |
| 84 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = CollectionUtils.convertMap(processDefinitionDOs, | |
| 85 | + BpmProcessDefinitionExtDO::getProcessDefinitionId); | |
| 85 | 86 | |
| 86 | 87 | // 获得 Form Map |
| 87 | - Set<Long> formIds = CollectionUtils.convertSet(processDefinitionDOs, BpmProcessDefinitionDO::getFormId); | |
| 88 | + Set<Long> formIds = CollectionUtils.convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId); | |
| 88 | 89 | Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds); |
| 89 | 90 | |
| 90 | 91 | // 拼接结果 |
| ... | ... | @@ -94,6 +95,27 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ |
| 94 | 95 | } |
| 95 | 96 | |
| 96 | 97 | @Override |
| 98 | + public List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO) { | |
| 99 | + // 拼接查询条件 | |
| 100 | + ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery(); | |
| 101 | + if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), listReqVO.getSuspensionState())) { | |
| 102 | + definitionQuery.suspended(); | |
| 103 | + } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), listReqVO.getSuspensionState())) { | |
| 104 | + definitionQuery.active(); | |
| 105 | + } | |
| 106 | + // 执行查询 | |
| 107 | + List<ProcessDefinition> processDefinitions = definitionQuery.list(); | |
| 108 | + | |
| 109 | + // 获得 BpmProcessDefinitionDO Map | |
| 110 | + List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds( | |
| 111 | + convertList(processDefinitions, ProcessDefinition::getId)); | |
| 112 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = CollectionUtils.convertMap(processDefinitionDOs, | |
| 113 | + BpmProcessDefinitionExtDO::getProcessDefinitionId); | |
| 114 | + // 执行查询,并返回 | |
| 115 | + return BpmDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap); | |
| 116 | + } | |
| 117 | + | |
| 118 | + @Override | |
| 97 | 119 | public String getProcessDefinitionBpmnXML(String id) { |
| 98 | 120 | BpmnModel bpmnModel = repositoryService.getBpmnModel(id); |
| 99 | 121 | if (bpmnModel == null) { |
| ... | ... | @@ -114,6 +136,11 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ |
| 114 | 136 | } |
| 115 | 137 | |
| 116 | 138 | @Override |
| 139 | + public ProcessDefinition getProcessDefinition2(String id) { | |
| 140 | + return repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult(); | |
| 141 | + } | |
| 142 | + | |
| 143 | + @Override | |
| 117 | 144 | public Deployment getDeployment(String id) { |
| 118 | 145 | if (StrUtil.isEmpty(id)) { |
| 119 | 146 | return null; |
| ... | ... | @@ -169,7 +196,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ |
| 169 | 196 | } |
| 170 | 197 | |
| 171 | 198 | // 插入拓展表 |
| 172 | - BpmProcessDefinitionDO definitionDO = BpmDefinitionConvert.INSTANCE.convert2(createReqDTO) | |
| 199 | + BpmProcessDefinitionExtDO definitionDO = BpmDefinitionConvert.INSTANCE.convert2(createReqDTO) | |
| 173 | 200 | .setProcessDefinitionId(definition.getId()); |
| 174 | 201 | processDefinitionMapper.insert(definitionDO); |
| 175 | 202 | return definition.getId(); | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/LeaveApplyEndProcessor.java
| ... | ... | @@ -2,7 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.oa; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO; |
| 4 | 4 | import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.oa.OALeaveMapper; |
| 5 | -import cn.iocoder.yudao.adminserver.modules.bpm.enums.FlowStatusEnum; | |
| 5 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 6 | 6 | import org.activiti.engine.delegate.DelegateExecution; |
| 7 | 7 | import org.activiti.engine.delegate.ExecutionListener; |
| 8 | 8 | import org.springframework.stereotype.Component; |
| ... | ... | @@ -29,9 +29,9 @@ public class LeaveApplyEndProcessor implements ExecutionListener { |
| 29 | 29 | OALeaveDO updateDo = new OALeaveDO(); |
| 30 | 30 | updateDo.setId(Long.valueOf(businessKey)); |
| 31 | 31 | if (Objects.equals(approved, true)) { |
| 32 | - updateDo.setStatus(FlowStatusEnum.PASS.getStatus()); | |
| 32 | + updateDo.setStatus(BpmProcessInstanceResultEnum.APPROVE.getResult()); | |
| 33 | 33 | } else { |
| 34 | - updateDo.setStatus(FlowStatusEnum.REJECTED.getStatus()); | |
| 34 | + updateDo.setStatus(BpmProcessInstanceResultEnum.REJECT.getResult()); | |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | leaveMapper.updateById(updateDo); | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/impl/OALeaveServiceImpl.java
| ... | ... | @@ -6,7 +6,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.*; |
| 6 | 6 | import cn.iocoder.yudao.adminserver.modules.bpm.convert.oa.OALeaveConvert; |
| 7 | 7 | import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO; |
| 8 | 8 | import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.oa.OALeaveMapper; |
| 9 | -import cn.iocoder.yudao.adminserver.modules.bpm.enums.FlowStatusEnum; | |
| 9 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 10 | 10 | import cn.iocoder.yudao.adminserver.modules.bpm.service.oa.OALeaveService; |
| 11 | 11 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysPostDO; |
| 12 | 12 | import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.dept.SysPostMapper; |
| ... | ... | @@ -62,7 +62,7 @@ public class OALeaveServiceImpl implements OALeaveService { |
| 62 | 62 | public Long createLeave(OALeaveCreateReqVO createReqVO) { |
| 63 | 63 | // 插入 OA 请假单 |
| 64 | 64 | OALeaveDO leave = OALeaveConvert.INSTANCE.convert(createReqVO); |
| 65 | - leave.setStatus(FlowStatusEnum.HANDLE.getStatus()); | |
| 65 | + leave.setStatus(BpmProcessInstanceResultEnum.PROCESS.getResult()); | |
| 66 | 66 | // TODO @jason:应该是存储 userId?? |
| 67 | 67 | leave.setUserId(SecurityFrameworkUtils.getLoginUser().getUsername()); |
| 68 | 68 | leaveMapper.insert(leave); | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.service.task; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO; | |
| 3 | 4 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; |
| 5 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; | |
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; | |
| 7 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; | |
| 8 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 9 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 10 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 11 | +import org.activiti.engine.history.HistoricProcessInstance; | |
| 12 | +import org.activiti.engine.runtime.ProcessInstance; | |
| 4 | 13 | |
| 5 | 14 | import javax.validation.Valid; |
| 15 | +import java.util.List; | |
| 16 | +import java.util.Map; | |
| 17 | +import java.util.Set; | |
| 6 | 18 | |
| 7 | 19 | /** |
| 8 | 20 | * 流程实例 Service 接口 |
| ... | ... | @@ -20,4 +32,120 @@ public interface BpmProcessInstanceService { |
| 20 | 32 | */ |
| 21 | 33 | String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO); |
| 22 | 34 | |
| 35 | + /** | |
| 36 | + * 取消流程实例 | |
| 37 | + * | |
| 38 | + * @param userId 用户编号 | |
| 39 | + * @param cancelReqVO 取消信息 | |
| 40 | + */ | |
| 41 | + void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO); | |
| 42 | + | |
| 43 | + /** | |
| 44 | + * 删除流程实例 | |
| 45 | + * | |
| 46 | + * @param id 流程编号 | |
| 47 | + * @param reason 删除原因。可选 {@link BpmProcessInstanceDeleteReasonEnum} | |
| 48 | + */ | |
| 49 | + @Deprecated | |
| 50 | + void deleteProcessInstance(String id, String reason); | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * 更新流程实例的结果 | |
| 54 | + * 1. 如果更新为已拒绝时,会进行任务的删除 | |
| 55 | + * | |
| 56 | + * @param id 流程编号 | |
| 57 | + * @param result 结果,{@link BpmProcessInstanceResultEnum} | |
| 58 | + */ | |
| 59 | + void updateProcessInstanceResult(String id, Integer result); | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * 获得流程实例的分页 | |
| 63 | + * | |
| 64 | + * @param userId 用户编号 | |
| 65 | + * @param pageReqVO 分页请求 | |
| 66 | + * @return 流程实例的分页 | |
| 67 | + */ | |
| 68 | + PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, | |
| 69 | + @Valid BpmProcessInstanceMyPageReqVO pageReqVO); | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * 获得流程实例 | |
| 73 | + * | |
| 74 | + * @param id 流程实例的编号 | |
| 75 | + * @return 流程实例 | |
| 76 | + */ | |
| 77 | + ProcessInstance getProcessInstance(String id); | |
| 78 | + | |
| 79 | + /** | |
| 80 | + * 获得流程实例列表 | |
| 81 | + * | |
| 82 | + * @param ids 流程实例的编号集合 | |
| 83 | + * @return 流程实例列表 | |
| 84 | + */ | |
| 85 | + List<ProcessInstance> getProcessInstances(Set<String> ids); | |
| 86 | + | |
| 87 | + /** | |
| 88 | + * 获得流程实例 Map | |
| 89 | + * | |
| 90 | + * @param ids 流程实例的编号集合 | |
| 91 | + * @return 流程实例列表 Map | |
| 92 | + */ | |
| 93 | + default Map<String, ProcessInstance> getProcessInstanceMap(Set<String> ids) { | |
| 94 | + return CollectionUtils.convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId); | |
| 95 | + } | |
| 96 | + | |
| 97 | + /** | |
| 98 | + * 获得历史的流程实例 | |
| 99 | + * | |
| 100 | + * @param id 流程实例的编号 | |
| 101 | + * @return 历史的流程实例 | |
| 102 | + */ | |
| 103 | + HistoricProcessInstance getHistoricProcessInstance(String id); | |
| 104 | + | |
| 105 | + /** | |
| 106 | + * 获得历史的流程实例列表 | |
| 107 | + * | |
| 108 | + * @param ids 流程实例的编号集合 | |
| 109 | + * @return 历史的流程实例列表 | |
| 110 | + */ | |
| 111 | + List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids); | |
| 112 | + | |
| 113 | + /** | |
| 114 | + * 获得历史的流程实例 Map | |
| 115 | + * | |
| 116 | + * @param ids 流程实例的编号集合 | |
| 117 | + * @return 历史的流程实例列表 Map | |
| 118 | + */ | |
| 119 | + default Map<String, HistoricProcessInstance> getHistoricProcessInstanceMap(Set<String> ids) { | |
| 120 | + return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId); | |
| 121 | + } | |
| 122 | + | |
| 123 | + /** | |
| 124 | + * 创建 ProcessInstance 拓展记录 | |
| 125 | + * | |
| 126 | + * @param instance 流程任务 | |
| 127 | + */ | |
| 128 | + void createProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance); | |
| 129 | + | |
| 130 | + /** | |
| 131 | + * 更新 ProcessInstance 拓展记录 | |
| 132 | + * | |
| 133 | + * @param instance 流程任务 | |
| 134 | + */ | |
| 135 | + void updateProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance); | |
| 136 | + | |
| 137 | + /** | |
| 138 | + * 更新 ProcessInstance 拓展记录为取消 | |
| 139 | + * | |
| 140 | + * @param instance 流程任务 | |
| 141 | + */ | |
| 142 | + void updateProcessInstanceExtCancel(org.activiti.api.process.model.ProcessInstance instance); | |
| 143 | + | |
| 144 | + /** | |
| 145 | + * 更新 ProcessInstance 拓展记录为完成 | |
| 146 | + * | |
| 147 | + * @param instance 流程任务 | |
| 148 | + */ | |
| 149 | + void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance); | |
| 150 | + | |
| 23 | 151 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmTaskService.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.service.task; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.*; | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; | |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 6 | +import org.activiti.engine.task.Task; | |
| 5 | 7 | |
| 8 | +import javax.validation.Valid; | |
| 6 | 9 | import java.util.List; |
| 10 | +import java.util.Map; | |
| 7 | 11 | |
| 8 | 12 | /** |
| 9 | - * 工作流用户任务服务接口 | |
| 13 | + * 流程任务 Service 接口 | |
| 14 | + * | |
| 15 | + * @author jason | |
| 16 | + * @author 芋道源码 | |
| 10 | 17 | */ |
| 11 | 18 | public interface BpmTaskService { |
| 12 | 19 | |
| 20 | + /** | |
| 21 | + * 获得流程任务列表 | |
| 22 | + * | |
| 23 | + * @param processInstanceId 流程实例的编号 | |
| 24 | + * @return 流程任务列表 | |
| 25 | + */ | |
| 26 | + List<Task> getTasksByProcessInstanceId(String processInstanceId); | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 获得流程任务列表 | |
| 30 | + * | |
| 31 | + * @param processInstanceIds 流程实例的编号数组 | |
| 32 | + * @return 流程任务列表 | |
| 33 | + */ | |
| 34 | + List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds); | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * 获得流程任务 Map | |
| 38 | + * | |
| 39 | + * @param processInstanceIds 流程实例的编号数组 | |
| 40 | + * @return 流程任务 Map | |
| 41 | + */ | |
| 42 | + default Map<String, List<Task>> getTaskMapByProcessInstanceIds(List<String> processInstanceIds) { | |
| 43 | + return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds), | |
| 44 | + Task::getProcessInstanceId); | |
| 45 | + } | |
| 13 | 46 | |
| 14 | 47 | /** |
| 15 | - * 获取当前用户的待办任务, 分页 | |
| 48 | + * 获得待办的流程任务分页 | |
| 49 | + * | |
| 50 | + * @param userId 用户编号 | |
| 51 | + * @param pageReqVO 分页请求 | |
| 52 | + * @return 流程任务分页 | |
| 16 | 53 | */ |
| 17 | - PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO); | |
| 54 | + PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO); | |
| 18 | 55 | |
| 19 | 56 | /** |
| 20 | - * 签收任务 | |
| 21 | - * @param taskId 用户任务id | |
| 57 | + * 获得已办的流程任务分页 | |
| 58 | + * | |
| 59 | + * @param userId 用户编号 | |
| 60 | + * @param pageReqVO 分页请求 | |
| 61 | + * @return 流程任务分页 | |
| 22 | 62 | */ |
| 23 | - void claimTask(String taskId); | |
| 63 | + PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO); | |
| 24 | 64 | |
| 25 | 65 | /** |
| 26 | - * 工作流,完成 userTask, 完成用户任务 一般传入参数 1。是否同意(variables). 2. 评论(comment) | |
| 27 | - * variables 变量名 和 评论 由前台传入 | |
| 28 | - * @param taskReq 任务参数 | |
| 66 | + * 将流程任务分配给指定用户 | |
| 67 | + * | |
| 68 | + * @param id 流程任务编号 | |
| 69 | + * @param userId 用户编号 | |
| 29 | 70 | */ |
| 30 | - void completeTask(TaskReqVO taskReq); | |
| 71 | + void updateTaskAssign(String id, Long userId); | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * 通过任务 | |
| 75 | + * | |
| 76 | + * @param reqVO 通过请求 | |
| 77 | + */ | |
| 78 | + void approveTask(@Valid BpmTaskApproveReqVO reqVO); | |
| 79 | + | |
| 80 | + /** | |
| 81 | + * 不通过任务 | |
| 82 | + * | |
| 83 | + * @param reqVO 不通过请求 | |
| 84 | + */ | |
| 85 | + void rejectTask(@Valid BpmTaskRejectReqVO reqVO); | |
| 31 | 86 | |
| 32 | 87 | /** |
| 33 | 88 | * 根据任务id, 查询已经完成的用户任务,未完成的用户任务 |
| 34 | 89 | * @param taskQuery 查询参数 一般 taskId |
| 35 | 90 | */ |
| 91 | + @Deprecated | |
| 36 | 92 | TaskHandleVO getTaskSteps(TaskQueryReqVO taskQuery); |
| 37 | 93 | |
| 38 | 94 | /** |
| 39 | 95 | * 根据流程实例id, 查询历史用户任务,包括已完成,未完成 |
| 40 | 96 | * @param processInstanceId 流程实例id |
| 41 | 97 | */ |
| 98 | + @Deprecated | |
| 42 | 99 | List<TaskStepVO> getHistorySteps(String processInstanceId); |
| 43 | 100 | |
| 44 | 101 | /** |
| 45 | - * 获取用户任务的 formKey, 对应外置表单, 需要根据formKey 对应业务表单 | |
| 46 | - * @param taskQuery 查询参数 ,一般taskId | |
| 47 | - */ | |
| 48 | - TodoTaskRespVO getTaskFormKey(TaskQueryReqVO taskQuery); | |
| 49 | - | |
| 50 | - | |
| 51 | - /** | |
| 52 | 102 | * 返回高亮的流转进程 |
| 53 | 103 | * @param processInstanceId 实例Id |
| 54 | 104 | * @return {@link FileResp} 返回文件 |
| 55 | 105 | */ |
| 56 | 106 | FileResp getHighlightImg(String processInstanceId); |
| 107 | + | |
| 108 | + // ========== Task 拓展表相关 ========== | |
| 109 | + | |
| 110 | + /** | |
| 111 | + * 创建 Task 拓展记录 | |
| 112 | + * | |
| 113 | + * @param task 任务实体 | |
| 114 | + */ | |
| 115 | + void createTaskExt(org.activiti.api.task.model.Task task); | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * 更新 Task 拓展记录 | |
| 119 | + * | |
| 120 | + * @param task 任务实体 | |
| 121 | + */ | |
| 122 | + void updateTaskExt(org.activiti.api.task.model.Task task); | |
| 123 | + | |
| 124 | + /** | |
| 125 | + * 更新 Task 拓展记录为取消 | |
| 126 | + * | |
| 127 | + * @param task 任务实体 | |
| 128 | + */ | |
| 129 | + void updateTaskExtCancel(org.activiti.api.task.model.Task task); | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * 更新 Task 拓展记录为完成 | |
| 133 | + * | |
| 134 | + * @param task 任务实体 | |
| 135 | + */ | |
| 136 | + void updateTaskExtComplete(org.activiti.api.task.model.Task task); | |
| 137 | + | |
| 57 | 138 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl; |
| 2 | 2 | |
| 3 | -import cn.hutool.core.lang.Assert; | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO; | |
| 4 | 5 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; |
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; | |
| 7 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; | |
| 8 | +import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmProcessInstanceConvert; | |
| 9 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; | |
| 10 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; | |
| 11 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; | |
| 12 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 13 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceStatusEnum; | |
| 5 | 14 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; |
| 6 | 15 | import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService; |
| 16 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService; | |
| 7 | 17 | import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; |
| 8 | -import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; | |
| 18 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 9 | 19 | import lombok.extern.slf4j.Slf4j; |
| 10 | 20 | import org.activiti.engine.HistoryService; |
| 11 | -import org.activiti.engine.RepositoryService; | |
| 12 | 21 | import org.activiti.engine.RuntimeService; |
| 13 | -import org.activiti.engine.TaskService; | |
| 14 | -import org.activiti.engine.history.HistoricProcessInstanceQuery; | |
| 15 | -import org.activiti.engine.impl.identity.Authentication; | |
| 22 | +import org.activiti.engine.history.HistoricProcessInstance; | |
| 16 | 23 | import org.activiti.engine.repository.ProcessDefinition; |
| 17 | 24 | import org.activiti.engine.runtime.ProcessInstance; |
| 18 | 25 | import org.activiti.engine.task.Task; |
| 26 | +import org.springframework.context.annotation.Lazy; | |
| 19 | 27 | import org.springframework.stereotype.Service; |
| 28 | +import org.springframework.transaction.annotation.Transactional; | |
| 20 | 29 | import org.springframework.validation.annotation.Validated; |
| 21 | 30 | |
| 22 | 31 | import javax.annotation.Resource; |
| 23 | -import java.util.Map; | |
| 32 | +import java.util.*; | |
| 24 | 33 | |
| 25 | -import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED; | |
| 26 | -import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS; | |
| 34 | +import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; | |
| 27 | 35 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 36 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 28 | 37 | |
| 29 | 38 | /** |
| 30 | 39 | * 流程实例 Service 实现类 |
| ... | ... | @@ -44,20 +53,23 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU |
| 44 | 53 | public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { |
| 45 | 54 | |
| 46 | 55 | @Resource |
| 47 | - private RepositoryService repositoryService; | |
| 48 | - @Resource | |
| 49 | 56 | private RuntimeService runtimeService; |
| 50 | 57 | @Resource |
| 51 | - private TaskService taskService; | |
| 52 | - @Resource | |
| 53 | 58 | private HistoryService historyService; |
| 54 | 59 | |
| 55 | 60 | @Resource |
| 56 | 61 | private SysUserService userService; |
| 57 | 62 | @Resource |
| 63 | + @Lazy // 解决循环依赖 | |
| 64 | + private BpmTaskService taskService; | |
| 65 | + @Resource | |
| 58 | 66 | private BpmProcessDefinitionService processDefinitionService; |
| 59 | 67 | |
| 68 | + @Resource | |
| 69 | + private BpmProcessInstanceExtMapper processInstanceExtMapper; | |
| 70 | + | |
| 60 | 71 | @Override |
| 72 | + @Transactional(rollbackFor = Exception.class) | |
| 61 | 73 | public String createProcessInstance(Long userId, BpmProcessInstanceCreateReqVO createReqVO) { |
| 62 | 74 | // 校验流程定义 |
| 63 | 75 | ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); |
| ... | ... | @@ -68,33 +80,141 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 68 | 80 | throw exception(PROCESS_DEFINITION_IS_SUSPENDED); |
| 69 | 81 | } |
| 70 | 82 | |
| 71 | - // 设置流程发起人 | |
| 72 | - Authentication.setAuthenticatedUserId(String.valueOf(userId)); | |
| 73 | - | |
| 74 | 83 | // 创建流程实例 |
| 75 | 84 | Map<String, Object> variables = createReqVO.getVariables(); |
| 76 | - variables.put("INITIATOR", userId); // TODO 芋艿:初始化人员 | |
| 77 | 85 | ProcessInstance instance = runtimeService.startProcessInstanceById(createReqVO.getProcessDefinitionId(), variables); |
| 86 | + // 设置流程名字 | |
| 87 | + runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); | |
| 88 | + | |
| 89 | + // TODO 芋艿:临时使用, 保证分配 | |
| 90 | + List<Task> tasks = taskService.getTasksByProcessInstanceId(instance.getId()); | |
| 91 | + tasks.forEach(task -> taskService.updateTaskAssign(task.getId(), userId)); | |
| 78 | 92 | |
| 79 | 93 | // 添加初始的评论 TODO 芋艿:在思考下 |
| 80 | - Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult(); | |
| 81 | - if (task != null) { | |
| 82 | - SysUserDO user = userService.getUser(userId); | |
| 83 | - Assert.notNull(user, "用户({})不存在", userId); | |
| 84 | - String type = "normal"; | |
| 85 | - taskService.addComment(task.getId(), instance.getProcessInstanceId(), type, | |
| 86 | - String.format("%s 发起流程申请", user.getNickname())); | |
| 87 | - // TODO 芋艿:应该不用下面两个步骤 | |
| 88 | -// taskService.setAssignee(task.getId(), String.valueOf(userId)); | |
| 89 | -// taskService.complete(task.getId(), variables); | |
| 90 | - } | |
| 94 | +// Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult(); | |
| 95 | +// if (task != null) { | |
| 96 | +// SysUserDO user = userService.getUser(userId); | |
| 97 | +// Assert.notNull(user, "用户({})不存在", userId); | |
| 98 | +// String type = "normal"; | |
| 99 | +// taskService.addComment(task.getId(), instance.getProcessInstanceId(), type, | |
| 100 | +// String.format("%s 发起流程申请", user.getNickname())); | |
| 101 | +// // TODO 芋艿:应该不用下面两个步骤 | |
| 102 | +//// taskService.setAssignee(task.getId(), String.valueOf(userId)); | |
| 103 | +//// taskService.complete(task.getId(), variables); | |
| 104 | +// } | |
| 91 | 105 | return instance.getId(); |
| 92 | 106 | } |
| 93 | 107 | |
| 94 | - public void getMyProcessInstancePage(Long userId) { | |
| 95 | - HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery() | |
| 96 | - .startedBy(String.valueOf(userId)) // 发起人是自己 | |
| 97 | - .orderByProcessInstanceStartTime().desc(); // 按照发起时间倒序 | |
| 108 | + @Override | |
| 109 | + @Transactional(rollbackFor = Exception.class) | |
| 110 | + public void cancelProcessInstance(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) { | |
| 111 | + // 校验流程实例存在 | |
| 112 | + ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); | |
| 113 | + if (instance == null) { | |
| 114 | + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); | |
| 115 | + } | |
| 116 | + // 只能取消自己的 | |
| 117 | + if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { | |
| 118 | + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); | |
| 119 | + } | |
| 120 | + | |
| 121 | + // 通过删除流程实例,实现流程实例的取消 | |
| 122 | + runtimeService.deleteProcessInstance(cancelReqVO.getId(), cancelReqVO.getReason()); | |
| 123 | + } | |
| 124 | + | |
| 125 | + @Override | |
| 126 | + public void deleteProcessInstance(String id, String reason) { | |
| 127 | + runtimeService.deleteProcessInstance(id, reason); | |
| 128 | + } | |
| 129 | + | |
| 130 | + @Override | |
| 131 | + @Transactional(rollbackFor = Exception.class) | |
| 132 | + public void updateProcessInstanceResult(String id, Integer result) { | |
| 133 | + // 删除流程实例,以实现驳回任务时,取消整个审批流程 | |
| 134 | + if (Objects.equals(result, BpmProcessInstanceResultEnum.REJECT.getResult())) { | |
| 135 | + deleteProcessInstance(id, BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.getReason()); | |
| 136 | + } | |
| 137 | + // 更新 status + result | |
| 138 | + processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(id) | |
| 139 | + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()).setResult(result)); | |
| 140 | + } | |
| 141 | + | |
| 142 | + @Override | |
| 143 | + public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, | |
| 144 | + BpmProcessInstanceMyPageReqVO pageReqVO) { | |
| 145 | + // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 | |
| 146 | + PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); | |
| 147 | + if (CollUtil.isEmpty(pageResult.getList())) { | |
| 148 | + return new PageResult<>(pageResult.getTotal()); | |
| 149 | + } | |
| 150 | + | |
| 151 | + // 获得流程 Task Map | |
| 152 | + List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); | |
| 153 | + Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); | |
| 154 | + // 转换返回 | |
| 155 | + return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap); | |
| 156 | + } | |
| 157 | + | |
| 158 | + @Override | |
| 159 | + public List<ProcessInstance> getProcessInstances(Set<String> ids) { | |
| 160 | + return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); | |
| 161 | + } | |
| 162 | + | |
| 163 | + @Override | |
| 164 | + public ProcessInstance getProcessInstance(String id) { | |
| 165 | + return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); | |
| 166 | + } | |
| 167 | + | |
| 168 | + /** | |
| 169 | + * 获得历史的流程实例 | |
| 170 | + * | |
| 171 | + * @param id 流程实例的编号 | |
| 172 | + * @return 历史的流程实例 | |
| 173 | + */ | |
| 174 | + @Override | |
| 175 | + public HistoricProcessInstance getHistoricProcessInstance(String id) { | |
| 176 | + return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); | |
| 177 | + } | |
| 178 | + | |
| 179 | + @Override | |
| 180 | + public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { | |
| 181 | + return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); | |
| 182 | + } | |
| 183 | + | |
| 184 | + @Override | |
| 185 | + public void createProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance) { | |
| 186 | + // 获得流程定义 | |
| 187 | + ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); | |
| 188 | + // 插入 BpmProcessInstanceExtDO 对象 | |
| 189 | + BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance) | |
| 190 | + .setCategory(definition.getCategory()) | |
| 191 | + .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) | |
| 192 | + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); | |
| 193 | + processInstanceExtMapper.insert(instanceExtDO); | |
| 194 | + } | |
| 195 | + | |
| 196 | + @Override | |
| 197 | + public void updateProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance) { | |
| 198 | + BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance); | |
| 199 | + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); | |
| 200 | + } | |
| 201 | + | |
| 202 | + @Override | |
| 203 | + public void updateProcessInstanceExtCancel(org.activiti.api.process.model.ProcessInstance instance) { | |
| 204 | + BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance) | |
| 205 | + .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 | |
| 206 | + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) | |
| 207 | + .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); | |
| 208 | + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); | |
| 209 | + } | |
| 210 | + | |
| 211 | + @Override | |
| 212 | + public void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance) { | |
| 213 | + BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance) | |
| 214 | + .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 | |
| 215 | + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) | |
| 216 | + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 | |
| 217 | + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); | |
| 98 | 218 | } |
| 99 | 219 | |
| 100 | 220 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java
| ... | ... | @@ -2,19 +2,20 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.io.IoUtil; |
| 5 | -import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.*; | |
| 6 | -import cn.iocoder.yudao.adminserver.modules.bpm.convert.workflow.TaskConvert; | |
| 5 | +import cn.hutool.core.util.StrUtil; | |
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; | |
| 7 | +import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert; | |
| 8 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO; | |
| 9 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmTaskExtMapper; | |
| 10 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum; | |
| 11 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService; | |
| 7 | 12 | import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService; |
| 13 | +import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | |
| 14 | +import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; | |
| 8 | 15 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 9 | 16 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 10 | -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | |
| 17 | +import cn.iocoder.yudao.framework.common.util.object.PageUtils; | |
| 11 | 18 | import lombok.extern.slf4j.Slf4j; |
| 12 | -import org.activiti.api.runtime.shared.query.Page; | |
| 13 | -import org.activiti.api.runtime.shared.query.Pageable; | |
| 14 | -import org.activiti.api.task.model.Task; | |
| 15 | -import org.activiti.api.task.model.builders.ClaimTaskPayloadBuilder; | |
| 16 | -import org.activiti.api.task.model.builders.TaskPayloadBuilder; | |
| 17 | -import org.activiti.api.task.runtime.TaskRuntime; | |
| 18 | 19 | import org.activiti.bpmn.constants.BpmnXMLConstants; |
| 19 | 20 | import org.activiti.bpmn.model.BpmnModel; |
| 20 | 21 | import org.activiti.bpmn.model.FlowNode; |
| ... | ... | @@ -22,100 +23,210 @@ import org.activiti.bpmn.model.SequenceFlow; |
| 22 | 23 | import org.activiti.engine.HistoryService; |
| 23 | 24 | import org.activiti.engine.RepositoryService; |
| 24 | 25 | import org.activiti.engine.RuntimeService; |
| 26 | +import org.activiti.engine.TaskService; | |
| 25 | 27 | import org.activiti.engine.history.HistoricActivityInstance; |
| 26 | 28 | import org.activiti.engine.history.HistoricProcessInstance; |
| 29 | +import org.activiti.engine.history.HistoricTaskInstance; | |
| 30 | +import org.activiti.engine.history.HistoricTaskInstanceQuery; | |
| 27 | 31 | import org.activiti.engine.repository.ProcessDefinition; |
| 28 | 32 | import org.activiti.engine.runtime.ProcessInstance; |
| 29 | 33 | import org.activiti.engine.task.Comment; |
| 34 | +import org.activiti.engine.task.Task; | |
| 35 | +import org.activiti.engine.task.TaskQuery; | |
| 30 | 36 | import org.activiti.image.ProcessDiagramGenerator; |
| 37 | +import org.springframework.context.annotation.Lazy; | |
| 31 | 38 | import org.springframework.stereotype.Service; |
| 32 | 39 | import org.springframework.transaction.annotation.Transactional; |
| 33 | 40 | import org.springframework.util.ObjectUtils; |
| 34 | 41 | |
| 35 | 42 | import javax.annotation.Resource; |
| 43 | +import javax.validation.Valid; | |
| 36 | 44 | import java.io.IOException; |
| 37 | 45 | import java.io.InputStream; |
| 38 | -import java.util.ArrayList; | |
| 39 | -import java.util.List; | |
| 40 | -import java.util.Map; | |
| 41 | -import java.util.Optional; | |
| 42 | -import java.util.stream.Collectors; | |
| 43 | - | |
| 44 | -import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.HIGHLIGHT_IMG_ERROR; | |
| 45 | -import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS; | |
| 46 | -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 46 | +import java.util.*; | |
| 47 | 47 | |
| 48 | +import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; | |
| 49 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 50 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | |
| 51 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 52 | + | |
| 53 | +/** | |
| 54 | + * 流程任务 Service 实现类 | |
| 55 | + * | |
| 56 | + * @author jason | |
| 57 | + * @author 芋道源码 | |
| 58 | + */ | |
| 48 | 59 | @Slf4j |
| 49 | 60 | @Service |
| 50 | 61 | public class BpmTaskServiceImpl implements BpmTaskService { |
| 51 | 62 | |
| 52 | 63 | @Resource |
| 53 | - private TaskRuntime taskRuntime; | |
| 54 | - | |
| 64 | + private TaskService taskService; | |
| 55 | 65 | @Resource |
| 56 | - private org.activiti.engine.TaskService activitiTaskService; | |
| 57 | - | |
| 66 | + private RuntimeService runtimeService; | |
| 58 | 67 | @Resource |
| 59 | 68 | private HistoryService historyService; |
| 60 | - | |
| 61 | 69 | @Resource |
| 62 | 70 | private RepositoryService repositoryService; |
| 63 | 71 | |
| 64 | 72 | @Resource |
| 65 | - private RuntimeService runtimeService; | |
| 73 | + private ProcessDiagramGenerator processDiagramGenerator; | |
| 66 | 74 | |
| 67 | 75 | @Resource |
| 68 | - private ProcessDiagramGenerator processDiagramGenerator; | |
| 76 | + private SysUserService userService; | |
| 77 | + @Resource | |
| 78 | + @Lazy // 解决循环依赖 | |
| 79 | + private BpmProcessInstanceService processInstanceService; | |
| 80 | + | |
| 81 | + @Resource | |
| 82 | + private BpmTaskExtMapper taskExtMapper; | |
| 69 | 83 | |
| 70 | 84 | @Override |
| 71 | - public PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO) { | |
| 72 | - // TODO @jason:封装一个方法,用于转换成 activiti 的分页对象 | |
| 73 | - final Pageable pageable = Pageable.of((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(), pageReqVO.getPageSize()); | |
| 74 | - Page<Task> pageTasks = taskRuntime.tasks(pageable); | |
| 75 | - int totalItems = pageTasks.getTotalItems(); | |
| 76 | - List<Task> tasks = pageTasks.getContent(); | |
| 77 | - final List<TodoTaskRespVO> respVOList = tasks.stream().map(task -> { | |
| 78 | - ProcessDefinition definition = repositoryService.getProcessDefinition(task.getProcessDefinitionId()); | |
| 79 | - return TaskConvert.INSTANCE.convert(task, definition); | |
| 80 | - }).collect(Collectors.toList()); | |
| 81 | - return new PageResult<>(respVOList, (long)totalItems); | |
| 85 | + public List<Task> getTasksByProcessInstanceId(String processInstanceId) { | |
| 86 | + return taskService.createTaskQuery().processInstanceId(processInstanceId).list(); | |
| 82 | 87 | } |
| 83 | 88 | |
| 89 | + @Override | |
| 90 | + public List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds) { | |
| 91 | + if (CollUtil.isEmpty(processInstanceIds)) { | |
| 92 | + return Collections.emptyList(); | |
| 93 | + } | |
| 94 | + return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list(); | |
| 95 | + } | |
| 84 | 96 | |
| 85 | 97 | @Override |
| 86 | - public void claimTask(String taskId) { | |
| 87 | - taskRuntime.claim(new ClaimTaskPayloadBuilder() | |
| 88 | - .withTaskId(taskId) | |
| 89 | - .withAssignee(SecurityFrameworkUtils.getLoginUser().getUsername()) | |
| 90 | - .build()); | |
| 98 | + public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { | |
| 99 | + // 查询待办任务 | |
| 100 | + TaskQuery taskQuery = taskService.createTaskQuery() | |
| 101 | + .taskAssignee(String.valueOf(userId)) // 分配给自己 | |
| 102 | + .orderByTaskCreateTime().desc(); // 创建时间倒序 | |
| 103 | + if (StrUtil.isNotBlank(pageVO.getName())) { | |
| 104 | + taskQuery.taskNameLike("%" + pageVO.getName() + "%"); | |
| 105 | + } | |
| 106 | + if (pageVO.getBeginCreateTime() != null) { | |
| 107 | + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime()); | |
| 108 | + } | |
| 109 | + if (pageVO.getEndCreateTime() != null) { | |
| 110 | + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime()); | |
| 111 | + } | |
| 112 | + // 执行查询 | |
| 113 | + List<Task> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); | |
| 114 | + if (CollUtil.isEmpty(tasks)) { | |
| 115 | + return PageResult.empty(taskQuery.count()); | |
| 116 | + } | |
| 117 | + | |
| 118 | + // 获得 ProcessInstance Map | |
| 119 | + Map<String, ProcessInstance> processInstanceMap = processInstanceService.getProcessInstanceMap( | |
| 120 | + convertSet(tasks, Task::getProcessInstanceId)); | |
| 121 | + // 获得 User Map | |
| 122 | + Map<Long, SysUserDO> userMap = userService.getUserMap( | |
| 123 | + convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); | |
| 124 | + // 拼接结果 | |
| 125 | + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList(tasks, processInstanceMap, userMap), | |
| 126 | + taskQuery.count()); | |
| 91 | 127 | } |
| 92 | 128 | |
| 129 | + @Override | |
| 130 | + public PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) { | |
| 131 | + // 查询已办任务 | |
| 132 | + HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery() | |
| 133 | + .finished() // 已完成 | |
| 134 | + .taskAssignee(String.valueOf(userId)) // 分配给自己 | |
| 135 | + .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序 | |
| 136 | + if (StrUtil.isNotBlank(pageVO.getName())) { | |
| 137 | + taskQuery.taskNameLike("%" + pageVO.getName() + "%"); | |
| 138 | + } | |
| 139 | + if (pageVO.getBeginCreateTime() != null) { | |
| 140 | + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime()); | |
| 141 | + } | |
| 142 | + if (pageVO.getEndCreateTime() != null) { | |
| 143 | + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime()); | |
| 144 | + } | |
| 145 | + // 执行查询 | |
| 146 | + List<HistoricTaskInstance> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); | |
| 147 | + if (CollUtil.isEmpty(tasks)) { | |
| 148 | + return PageResult.empty(taskQuery.count()); | |
| 149 | + } | |
| 93 | 150 | |
| 151 | + // 获得 TaskExtDO Map | |
| 152 | + List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId)); | |
| 153 | + Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId); | |
| 154 | + // 获得 ProcessInstance Map | |
| 155 | + Map<String, HistoricProcessInstance> historicProcessInstanceMap = processInstanceService.getHistoricProcessInstanceMap( | |
| 156 | + convertSet(tasks, HistoricTaskInstance::getProcessInstanceId)); | |
| 157 | + // 获得 User Map | |
| 158 | + Map<Long, SysUserDO> userMap = userService.getUserMap( | |
| 159 | + convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); | |
| 160 | + // 拼接结果 | |
| 161 | + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap), | |
| 162 | + taskQuery.count()); | |
| 163 | + } | |
| 94 | 164 | |
| 95 | 165 | @Override |
| 96 | - @Transactional | |
| 97 | - public void completeTask(TaskReqVO taskReq) { | |
| 98 | - final Task task = taskRuntime.task(taskReq.getTaskId()); | |
| 166 | + public void updateTaskAssign(String id, Long userId) { | |
| 167 | + taskService.setAssignee(id, String.valueOf(userId)); | |
| 168 | + } | |
| 169 | + | |
| 170 | + @Override | |
| 171 | + @Transactional(rollbackFor = Exception.class) | |
| 172 | + public void approveTask(BpmTaskApproveReqVO reqVO) { | |
| 173 | + // 校验任务存在 | |
| 174 | + Task task = getTask(reqVO.getId()); | |
| 175 | + if (task == null) { | |
| 176 | + throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); | |
| 177 | + } | |
| 178 | + // 校验流程实例存在 | |
| 179 | + ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); | |
| 180 | + if (instance == null) { | |
| 181 | + throw exception(PROCESS_INSTANCE_NOT_EXISTS); | |
| 182 | + } | |
| 99 | 183 | |
| 100 | - activitiTaskService.addComment(taskReq.getTaskId(), task.getProcessInstanceId(), taskReq.getComment()); | |
| 184 | + // 完成任务,审批通过 | |
| 185 | + taskService.complete(task.getId(), instance.getProcessVariables()); // TODO 芋艿:variables 的选择 | |
| 186 | + // 更新任务拓展表为通过 | |
| 187 | + taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) | |
| 188 | + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setComment(reqVO.getComment())); | |
| 101 | 189 | |
| 102 | - taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskReq.getTaskId()) | |
| 103 | - .withVariables(taskReq.getVariables()) | |
| 104 | - .build()); | |
| 190 | + // TODO 芋艿:添加评论 | |
| 191 | +// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment()); | |
| 105 | 192 | } |
| 106 | 193 | |
| 194 | + @Override | |
| 195 | + @Transactional(rollbackFor = Exception.class) | |
| 196 | + public void rejectTask(@Valid BpmTaskRejectReqVO reqVO) { | |
| 197 | + // 校验任务存在 | |
| 198 | + Task task = getTask(reqVO.getId()); | |
| 199 | + if (task == null) { | |
| 200 | + throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); | |
| 201 | + } | |
| 202 | + // 校验流程实例存在 | |
| 203 | + ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); | |
| 204 | + if (instance == null) { | |
| 205 | + throw exception(PROCESS_INSTANCE_NOT_EXISTS); | |
| 206 | + } | |
| 207 | + | |
| 208 | + // 更新流程实例为不通过 | |
| 209 | + processInstanceService.updateProcessInstanceResult(instance.getProcessInstanceId(), | |
| 210 | + BpmProcessInstanceResultEnum.REJECT.getResult()); | |
| 107 | 211 | |
| 212 | + // 更新任务拓展表为不通过 | |
| 213 | + taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) | |
| 214 | + .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment())); | |
| 215 | + | |
| 216 | + // TODO 芋艿:添加评论 | |
| 217 | +// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment()); | |
| 218 | + } | |
| 108 | 219 | |
| 109 | 220 | @Override |
| 110 | 221 | public TaskHandleVO getTaskSteps(TaskQueryReqVO taskQuery) { |
| 111 | - TaskHandleVO handleVO = new TaskHandleVO(); | |
| 112 | - final Task task = taskRuntime.task(taskQuery.getTaskId()); | |
| 113 | - List<TaskStepVO> steps = getTaskSteps(task.getProcessInstanceId()); | |
| 114 | - handleVO.setHistoryTask(steps); | |
| 115 | - return handleVO; | |
| 222 | +// TaskHandleVO handleVO = new TaskHandleVO(); | |
| 223 | +// final Task task = taskRuntime.task(taskQuery.getTaskId()); | |
| 224 | +// List<TaskStepVO> steps = getTaskSteps(task.getProcessInstanceId()); | |
| 225 | +// handleVO.setHistoryTask(steps); | |
| 226 | +// return handleVO; | |
| 227 | + return null; | |
| 116 | 228 | } |
| 117 | 229 | |
| 118 | - | |
| 119 | 230 | private List<TaskStepVO> getTaskSteps(String processInstanceId) { |
| 120 | 231 | // 获得已完成的活动 |
| 121 | 232 | List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery() |
| ... | ... | @@ -126,10 +237,10 @@ public class BpmTaskServiceImpl implements BpmTaskService { |
| 126 | 237 | // 获得对应的步骤 |
| 127 | 238 | List<TaskStepVO> steps = new ArrayList<>(); |
| 128 | 239 | finished.forEach(instance -> { |
| 129 | - TaskStepVO stepVO = TaskConvert.INSTANCE.convert(instance); | |
| 240 | + TaskStepVO stepVO = BpmTaskConvert.INSTANCE.convert(instance); | |
| 130 | 241 | stepVO.setStatus(1); // TODO @jason:1 这个 magic number 要枚举起来。 |
| 131 | 242 | // TODO @jason:可以考虑把 comments 读取后,在统一调用 convert 拼接。另外 Comment 是废弃的类,有没其它可以使用的哈? |
| 132 | - List<Comment> comments = activitiTaskService.getTaskComments(instance.getTaskId()); | |
| 243 | + List<Comment> comments = taskService.getTaskComments(instance.getTaskId()); | |
| 133 | 244 | if (!CollUtil.isEmpty(comments)) { |
| 134 | 245 | stepVO.setComment(Optional.ofNullable(comments.get(0)).map(Comment::getFullMessage).orElse("")); |
| 135 | 246 | } |
| ... | ... | @@ -144,7 +255,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { |
| 144 | 255 | .unfinished().list(); |
| 145 | 256 | // 获得对应的步骤 |
| 146 | 257 | for (HistoricActivityInstance instance : unfinished) { |
| 147 | - TaskStepVO stepVO = TaskConvert.INSTANCE.convert(instance); | |
| 258 | + TaskStepVO stepVO = BpmTaskConvert.INSTANCE.convert(instance); | |
| 148 | 259 | stepVO.setComment(""); |
| 149 | 260 | stepVO.setStatus(0); |
| 150 | 261 | steps.add(stepVO); |
| ... | ... | @@ -159,12 +270,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { |
| 159 | 270 | } |
| 160 | 271 | |
| 161 | 272 | @Override |
| 162 | - public TodoTaskRespVO getTaskFormKey(TaskQueryReqVO taskQuery) { | |
| 163 | - final Task task = taskRuntime.task(taskQuery.getTaskId()); | |
| 164 | - return TaskConvert.INSTANCE.convert(task); | |
| 165 | - } | |
| 166 | - | |
| 167 | - @Override | |
| 168 | 273 | public FileResp getHighlightImg(String processInstanceId) { |
| 169 | 274 | // 查询历史 |
| 170 | 275 | //TODO 云扬四海 貌似流程结束后,点击审批进度会报错 |
| ... | ... | @@ -172,7 +277,8 @@ public class BpmTaskServiceImpl implements BpmTaskService { |
| 172 | 277 | HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); |
| 173 | 278 | // 如果不存在实例。 说明数据异常 |
| 174 | 279 | if (hpi == null) { |
| 175 | - throw exception(PROCESS_INSTANCE_NOT_EXISTS); | |
| 280 | +// throw exception(PROCESS_INSTANCE_NOT_EXISTS); | |
| 281 | + throw new RuntimeException("不存在"); | |
| 176 | 282 | } |
| 177 | 283 | // 如果有结束时间 返回model的流程图 |
| 178 | 284 | if (!ObjectUtils.isEmpty(hpi.getEndTime())) { |
| ... | ... | @@ -285,4 +391,41 @@ public class BpmTaskServiceImpl implements BpmTaskService { |
| 285 | 391 | } |
| 286 | 392 | return highLightedFlowIds; |
| 287 | 393 | } |
| 394 | + | |
| 395 | + private Task getTask(String id) { | |
| 396 | + return taskService.createTaskQuery().taskId(id).singleResult(); | |
| 397 | + } | |
| 398 | + | |
| 399 | + // ========== Task 拓展表相关 ========== | |
| 400 | + | |
| 401 | + @Override | |
| 402 | + public void createTaskExt(org.activiti.api.task.model.Task task) { | |
| 403 | + // 插入 BpmTaskExtDO 记录 | |
| 404 | + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task) | |
| 405 | + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); | |
| 406 | + taskExtMapper.insert(taskExtDO); | |
| 407 | + } | |
| 408 | + | |
| 409 | + @Override | |
| 410 | + public void updateTaskExt(org.activiti.api.task.model.Task task) { | |
| 411 | + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task); | |
| 412 | + taskExtMapper.updateByTaskId(taskExtDO); | |
| 413 | + } | |
| 414 | + | |
| 415 | + @Override | |
| 416 | + public void updateTaskExtCancel(org.activiti.api.task.model.Task task) { | |
| 417 | + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task) | |
| 418 | + .setEndTime(new Date()) // 由于 Task 里没有办法拿到 endTime,所以这里设置 | |
| 419 | + .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); | |
| 420 | + taskExtMapper.updateByTaskId(taskExtDO); | |
| 421 | + } | |
| 422 | + | |
| 423 | + @Override | |
| 424 | + public void updateTaskExtComplete(org.activiti.api.task.model.Task task) { | |
| 425 | + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task) | |
| 426 | + .setEndTime(task.getCompletedDate()) | |
| 427 | + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); | |
| 428 | + taskExtMapper.updateByTaskId(taskExtDO); | |
| 429 | + } | |
| 430 | + | |
| 288 | 431 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/listener/BpmProcessInstanceEventListener.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService; | |
| 5 | +import org.activiti.api.model.shared.event.RuntimeEvent; | |
| 6 | +import org.activiti.api.process.model.ProcessInstance; | |
| 7 | +import org.activiti.api.process.model.events.ProcessRuntimeEvent; | |
| 8 | +import org.activiti.api.process.runtime.events.listener.ProcessEventListener; | |
| 9 | +import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener; | |
| 10 | +import org.activiti.api.task.model.events.TaskRuntimeEvent; | |
| 11 | +import org.springframework.context.annotation.Lazy; | |
| 12 | +import org.springframework.stereotype.Component; | |
| 13 | + | |
| 14 | +import javax.annotation.Resource; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * 监听 {@link ProcessInstance} 的开始与完成,创建与更新对应的 {@link BpmProcessInstanceExtDO} 记录 | |
| 18 | + * | |
| 19 | + * @author 芋道源码 | |
| 20 | + */ | |
| 21 | +@Component | |
| 22 | +public class BpmProcessInstanceEventListener<T extends RuntimeEvent<?, ?>> | |
| 23 | + implements ProcessRuntimeEventListener<T> { | |
| 24 | + | |
| 25 | + @Resource | |
| 26 | + @Lazy // 解决循环依赖 | |
| 27 | + private BpmProcessInstanceService processInstanceService; | |
| 28 | + | |
| 29 | + @Override | |
| 30 | + @SuppressWarnings("unchecked") | |
| 31 | + public void onEvent(T rawEvent) { | |
| 32 | + // 由于 ProcessRuntimeEventListener 无法保证只监听 ProcessRuntimeEvent 事件,所以通过这样的方式 | |
| 33 | + if (!(rawEvent instanceof ProcessRuntimeEvent)) { | |
| 34 | + return; | |
| 35 | + } | |
| 36 | + ProcessRuntimeEvent<ProcessInstance> event = (ProcessRuntimeEvent<ProcessInstance>) rawEvent; | |
| 37 | + | |
| 38 | + // 创建时,插入拓展表 | |
| 39 | + if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED) { | |
| 40 | + processInstanceService.createProcessInstanceExt(event.getEntity()); | |
| 41 | + return; | |
| 42 | + } | |
| 43 | + // 取消时,更新拓展表为取消 | |
| 44 | + if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_CANCELLED) { | |
| 45 | + processInstanceService.updateProcessInstanceExtCancel(event.getEntity()); | |
| 46 | + return; | |
| 47 | + } | |
| 48 | + // 完成时,更新拓展表为已完成 | |
| 49 | + if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_COMPLETED) { | |
| 50 | + processInstanceService.updateProcessInstanceExtComplete(event.getEntity()); | |
| 51 | + return; | |
| 52 | + } | |
| 53 | + | |
| 54 | + // 其它事件,进行更新拓展表 | |
| 55 | + processInstanceService.updateProcessInstanceExt(event.getEntity()); | |
| 56 | + } | |
| 57 | + | |
| 58 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/listener/BpmTackActivitiEventListener.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; | |
| 5 | +import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener; | |
| 6 | +import org.activiti.api.task.runtime.events.listener.TaskEventListener; | |
| 7 | +import org.activiti.engine.delegate.event.ActivitiEvent; | |
| 8 | +import org.activiti.engine.delegate.event.ActivitiEventListener; | |
| 9 | +import org.activiti.engine.delegate.event.ActivitiEventType; | |
| 10 | +import org.activiti.engine.delegate.event.impl.ActivitiEntityEventImpl; | |
| 11 | +import org.activiti.engine.impl.persistence.entity.TaskEntity; | |
| 12 | +import org.activiti.engine.repository.ProcessDefinition; | |
| 13 | +import org.springframework.context.annotation.Lazy; | |
| 14 | +import org.springframework.stereotype.Component; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * 监听 {@link TaskEntity} 相关的事件,设置相关属性。 | |
| 20 | + * 目的:解决 {@link TaskEventListener} 无法解决的场景 | |
| 21 | + * | |
| 22 | + * @author 芋道源码 | |
| 23 | + */ | |
| 24 | +@Component | |
| 25 | +public class BpmTackActivitiEventListener implements ActivitiEventListener { | |
| 26 | + | |
| 27 | + @Resource | |
| 28 | + @Lazy // 解决循环依赖 | |
| 29 | + private BpmProcessDefinitionService processDefinitionService; | |
| 30 | + | |
| 31 | + @Override | |
| 32 | + public void onEvent(ActivitiEvent event) { | |
| 33 | + // Task 创建时,设置其分类,解决 TaskService 未提供 name 的设置方法 | |
| 34 | + if (ActivitiEventType.TASK_CREATED == event.getType()) { | |
| 35 | + TaskEntity task = ((TaskEntity) ((ActivitiEntityEventImpl) event).getEntity()); | |
| 36 | + if (StrUtil.isNotEmpty(task.getCategory())) { | |
| 37 | + return; | |
| 38 | + } | |
| 39 | + // 设置 name | |
| 40 | + ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition2(task.getProcessDefinitionId()); | |
| 41 | + if (processDefinition == null) { | |
| 42 | + return; | |
| 43 | + } | |
| 44 | + task.setCategory(processDefinition.getCategory()); | |
| 45 | + } | |
| 46 | + } | |
| 47 | + | |
| 48 | + @Override | |
| 49 | + public boolean isFailOnException() { | |
| 50 | + return true; | |
| 51 | + } | |
| 52 | + | |
| 53 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/listener/BpmTaskEventListener.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService; | |
| 5 | +import org.activiti.api.task.model.Task; | |
| 6 | +import org.activiti.api.task.model.events.TaskRuntimeEvent; | |
| 7 | +import org.activiti.api.task.runtime.events.listener.TaskEventListener; | |
| 8 | +import org.springframework.context.annotation.Lazy; | |
| 9 | +import org.springframework.stereotype.Component; | |
| 10 | + | |
| 11 | +import javax.annotation.Resource; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * 监听 {@link Task} 的开始与完成,创建与更新对应的 {@link BpmTaskExtDO} 记录 | |
| 15 | + * | |
| 16 | + * @author 芋道源码 | |
| 17 | + */ | |
| 18 | +@Component | |
| 19 | +public class BpmTaskEventListener<T extends TaskRuntimeEvent<? extends Task>> | |
| 20 | + implements TaskEventListener<T> { | |
| 21 | + | |
| 22 | + @Resource | |
| 23 | + @Lazy // 解决循环依赖 | |
| 24 | + private BpmTaskService taskService; | |
| 25 | + | |
| 26 | + @Override | |
| 27 | + public void onEvent(T event) { | |
| 28 | + // 创建时,插入拓展表 | |
| 29 | + if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_CREATED) { | |
| 30 | + taskService.createTaskExt(event.getEntity()); | |
| 31 | + return; | |
| 32 | + } | |
| 33 | + | |
| 34 | + // 取消时,更新拓展表为取消 | |
| 35 | + if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_CANCELLED) { | |
| 36 | + taskService.updateTaskExtCancel(event.getEntity()); | |
| 37 | + return; | |
| 38 | + } | |
| 39 | + // 完成时,更新拓展表为已完成。要注意,在调用 delete ProcessInstance 才会触发该逻辑 | |
| 40 | + if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_COMPLETED) { | |
| 41 | + taskService.updateTaskExtComplete(event.getEntity()); | |
| 42 | + return; | |
| 43 | + } | |
| 44 | + | |
| 45 | + // 其它事件,进行更新拓展表 | |
| 46 | + taskService.updateTaskExt(event.getEntity()); | |
| 47 | + } | |
| 48 | + | |
| 49 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java
| ... | ... | @@ -176,6 +176,9 @@ public class SysUserServiceImpl implements SysUserService { |
| 176 | 176 | |
| 177 | 177 | @Override |
| 178 | 178 | public List<SysUserDO> getUsers(Collection<Long> ids) { |
| 179 | + if (CollUtil.isEmpty(ids)) { | |
| 180 | + return Collections.emptyList(); | |
| 181 | + } | |
| 179 | 182 | return userMapper.selectBatchIds(ids); |
| 180 | 183 | } |
| 181 | 184 | ... | ... |
yudao-admin-ui/package.json
| ... | ... | @@ -85,7 +85,7 @@ |
| 85 | 85 | "@vue/compiler-sfc": "^3.0.1", |
| 86 | 86 | "@vue/eslint-config-prettier": "^5.0.0", |
| 87 | 87 | "axios": "^0.21.1", |
| 88 | - "bpmn-js": "^7.4.0", | |
| 88 | + "bpmn-js": "^8.8.3", | |
| 89 | 89 | "bpmn-js-properties-panel": "^0.37.2", |
| 90 | 90 | "camunda-bpmn-moddle": "^4.4.1", |
| 91 | 91 | "compression-webpack-plugin": "^6.1.1", | ... | ... |
yudao-admin-ui/src/api/bpm/definition.js
| ... | ... | @@ -8,6 +8,14 @@ export function getProcessDefinitionPage(query) { |
| 8 | 8 | }) |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | +export function getProcessDefinitionList(query) { | |
| 12 | + return request({ | |
| 13 | + url: '/bpm/process-definition/list', | |
| 14 | + method: 'get', | |
| 15 | + params: query | |
| 16 | + }) | |
| 17 | +} | |
| 18 | + | |
| 11 | 19 | export function getProcessDefinitionBpmnXML(id) { |
| 12 | 20 | return request({ |
| 13 | 21 | url: '/bpm/process-definition/get-bpmn-xml?id=' + id, | ... | ... |
yudao-admin-ui/src/api/bpm/processInstance.js
0 → 100644
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +export function getMyProcessInstancePage(query) { | |
| 4 | + return request({ | |
| 5 | + url: '/bpm/process-instance/my-page', | |
| 6 | + method: 'get', | |
| 7 | + params: query | |
| 8 | + }) | |
| 9 | +} | |
| 10 | + | |
| 11 | +export function createProcessInstance(data) { | |
| 12 | + return request({ | |
| 13 | + url: '/bpm/process-instance/create', | |
| 14 | + method: 'POST', | |
| 15 | + data: data | |
| 16 | + }) | |
| 17 | +} | |
| 18 | + | |
| 19 | +export function cancelProcessInstance(id, reason) { | |
| 20 | + return request({ | |
| 21 | + url: '/bpm/process-instance/cancel', | |
| 22 | + method: 'DELETE', | |
| 23 | + data: { | |
| 24 | + id, | |
| 25 | + reason | |
| 26 | + } | |
| 27 | + }) | |
| 28 | +} | ... | ... |
yudao-admin-ui/src/api/bpm/task.js
0 → 100644
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +export function getTodoTaskPage(query) { | |
| 4 | + return request({ | |
| 5 | + url: '/bpm/task/todo-page', | |
| 6 | + method: 'get', | |
| 7 | + params: query | |
| 8 | + }) | |
| 9 | +} | |
| 10 | + | |
| 11 | +export function getDoneTaskPage(query) { | |
| 12 | + return request({ | |
| 13 | + url: '/bpm/task/done-page', | |
| 14 | + method: 'get', | |
| 15 | + params: query | |
| 16 | + }) | |
| 17 | +} | |
| 18 | + | |
| 19 | +export function completeTask(data) { | |
| 20 | + return request({ | |
| 21 | + url: '/bpm/task/complete', | |
| 22 | + method: 'PUT', | |
| 23 | + data: data | |
| 24 | + }) | |
| 25 | +} | |
| 26 | + | |
| 27 | +export function approveTask(data) { | |
| 28 | + return request({ | |
| 29 | + url: '/bpm/task/approve', | |
| 30 | + method: 'PUT', | |
| 31 | + data: data | |
| 32 | + }) | |
| 33 | +} | |
| 34 | + | |
| 35 | +export function rejectTask(data) { | |
| 36 | + return request({ | |
| 37 | + url: '/bpm/task/reject', | |
| 38 | + method: 'PUT', | |
| 39 | + data: data | |
| 40 | + }) | |
| 41 | +} | ... | ... |
yudao-admin-ui/src/components/bpmnProcessDesigner/package/designer/plugins/palette/index.js
yudao-admin-ui/src/components/bpmnProcessDesigner/package/penal/base/ElementBaseInfo.vue
| 1 | 1 | <template> |
| 2 | 2 | <div class="panel-tab__content"> |
| 3 | 3 | <el-form size="mini" label-width="90px" :model="model" :rules="rules" @submit.native.prevent> |
| 4 | - <el-form-item label="流程标识" prop="key"> | |
| 5 | - <el-input v-model="model.key" placeholder="请输入流标标识" | |
| 6 | - :disabled="model.id !== undefined && model.id.length > 0" @change="handleKeyUpdate" /> | |
| 7 | - </el-form-item> | |
| 8 | - <el-form-item label="流程名称" prop="name"> | |
| 9 | - <el-input v-model="model.name" placeholder="请输入流程名称" clearable @change="handleNameUpdate" /> | |
| 10 | - </el-form-item> | |
| 11 | - <el-form-item label="流程分类" prop="category"> | |
| 12 | - <el-select v-model="model.category" placeholder="请选择流程分类" clearable style="width: 100%"> | |
| 13 | - <el-option v-for="dict in categoryDictDatas" :key="dict.value" :label="dict.label" :value="dict.value"/> | |
| 14 | - </el-select> | |
| 15 | - </el-form-item> | |
| 16 | - <el-form-item label="流程表单" prop="formId"> | |
| 17 | - <el-select v-model="model.formId" placeholder="请选择流程表单,非必选哟!" clearable style="width: 100%"> | |
| 18 | - <el-option v-for="form in forms" :key="form.id" :label="form.name" :value="form.id"/> | |
| 19 | - </el-select> | |
| 20 | - </el-form-item> | |
| 21 | - <el-form-item label="流程描述" prop="description"> | |
| 22 | - <el-input type="textarea" v-model="model.description" clearable @change="handleDescriptionUpdate" /> | |
| 23 | - </el-form-item> | |
| 4 | + <div v-if="elementBaseInfo.$type === 'bpmn:Process'"> <!-- 如果是 Process 信息的时候,使用自定义表单 --> | |
| 5 | + <el-form-item label="流程标识" prop="key"> | |
| 6 | + <el-input v-model="model.key" placeholder="请输入流标标识" | |
| 7 | + :disabled="model.id !== undefined && model.id.length > 0" @change="handleKeyUpdate" /> | |
| 8 | + </el-form-item> | |
| 9 | + <el-form-item label="流程名称" prop="name"> | |
| 10 | + <el-input v-model="model.name" placeholder="请输入流程名称" clearable @change="handleNameUpdate" /> | |
| 11 | + </el-form-item> | |
| 12 | + <el-form-item label="流程分类" prop="category"> | |
| 13 | + <el-select v-model="model.category" placeholder="请选择流程分类" clearable style="width: 100%"> | |
| 14 | + <el-option v-for="dict in categoryDictDatas" :key="dict.value" :label="dict.label" :value="dict.value"/> | |
| 15 | + </el-select> | |
| 16 | + </el-form-item> | |
| 17 | + <el-form-item label="流程表单" prop="formId"> | |
| 18 | + <el-select v-model="model.formId" placeholder="请选择流程表单,非必选哟!" clearable style="width: 100%"> | |
| 19 | + <el-option v-for="form in forms" :key="form.id" :label="form.name" :value="form.id"/> | |
| 20 | + </el-select> | |
| 21 | + </el-form-item> | |
| 22 | + <el-form-item label="流程描述" prop="description"> | |
| 23 | + <el-input type="textarea" v-model="model.description" clearable @change="handleDescriptionUpdate" /> | |
| 24 | + </el-form-item> | |
| 25 | + </div> | |
| 26 | + <div v-else> | |
| 27 | + <el-form-item label="ID"> | |
| 28 | + <el-input v-model="elementBaseInfo.id" clearable @change="updateBaseInfo('id')"/> | |
| 29 | + </el-form-item> | |
| 30 | + <el-form-item label="名称"> | |
| 31 | + <el-input v-model="elementBaseInfo.name" clearable @change="updateBaseInfo('name')" /> | |
| 32 | + </el-form-item> | |
| 33 | + </div> | |
| 24 | 34 | </el-form> |
| 25 | 35 | </div> |
| 26 | 36 | </template> | ... | ... |
yudao-admin-ui/src/components/parser/Parser.vue
| ... | ... | @@ -173,8 +173,13 @@ export default { |
| 173 | 173 | submitForm() { |
| 174 | 174 | this.$refs[this.formConf.formRef].validate(valid => { |
| 175 | 175 | if (!valid) return false |
| 176 | - // 触发sumit事件 | |
| 177 | - this.$emit('submit', this[this.formConf.formModel]) | |
| 176 | + // 触发 submit 事件 | |
| 177 | + // update by 芋道源码 | |
| 178 | + // this.$emit('submit', this[this.formConf.formModel]) | |
| 179 | + this.$emit('submit', { | |
| 180 | + conf: this.formConfCopy, | |
| 181 | + values: this[this.formConf.formModel] | |
| 182 | + }) | |
| 178 | 183 | return true |
| 179 | 184 | }) |
| 180 | 185 | } | ... | ... |
yudao-admin-ui/src/router/index.js
| ... | ... | @@ -188,6 +188,18 @@ export const constantRoutes = [ |
| 188 | 188 | meta: { title: '流程定义' } |
| 189 | 189 | } |
| 190 | 190 | ] |
| 191 | + }, { | |
| 192 | + path: '/bpm', | |
| 193 | + component: Layout, | |
| 194 | + hidden: true, | |
| 195 | + children: [ | |
| 196 | + { | |
| 197 | + path: 'process-instance/create', | |
| 198 | + component: (resolve) => require(['@/views/bpm/processInstance/create'], resolve), | |
| 199 | + name: '发起流程', | |
| 200 | + meta: { title: '发起流程' } | |
| 201 | + } | |
| 202 | + ] | |
| 191 | 203 | }, |
| 192 | 204 | ] |
| 193 | 205 | ... | ... |
yudao-admin-ui/src/utils/dateUtils.js
0 → 100644
| 1 | +/** | |
| 2 | + * 将毫秒,转换成时间字符串。例如说,xx 分钟 | |
| 3 | + * | |
| 4 | + * @param ms 毫秒 | |
| 5 | + * @returns {string} 字符串 | |
| 6 | + */ | |
| 7 | +export function getDate(ms) { | |
| 8 | + const day = Math.floor(ms / (24 * 60 * 60 * 1000)); | |
| 9 | + const hour = Math.floor((ms / (60 * 60 * 1000) - day * 24)); | |
| 10 | + const minute = Math.floor(((ms / (60 * 1000)) - day * 24 * 60 - hour * 60)); | |
| 11 | + const second = Math.floor((ms / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60)); | |
| 12 | + if (day > 0) { | |
| 13 | + return day + "天" + hour + "小时" + minute + "分钟"; | |
| 14 | + } | |
| 15 | + if (hour > 0) { | |
| 16 | + return hour + "小时" + minute + "分钟"; | |
| 17 | + } | |
| 18 | + if (minute > 0) { | |
| 19 | + return minute + "分钟"; | |
| 20 | + } | |
| 21 | + if (second > 0) { | |
| 22 | + return second + "秒"; | |
| 23 | + } else { | |
| 24 | + return 0 + "秒"; | |
| 25 | + } | |
| 26 | +} | ... | ... |
yudao-admin-ui/src/utils/dict.js
| ... | ... | @@ -36,6 +36,8 @@ export const DICT_TYPE = { |
| 36 | 36 | |
| 37 | 37 | // bpm |
| 38 | 38 | BPM_MODEL_CATEGORY: 'bpm_model_category', |
| 39 | + BPM_PROCESS_INSTANCE_STATUS: 'bpm_process_instance_status', | |
| 40 | + BPM_PROCESS_INSTANCE_RESULT: 'bpm_process_instance_result', | |
| 39 | 41 | OA_LEAVE_STATUS: 'flow_status', |
| 40 | 42 | OA_LEAVE_TYPE: 'oa_leave_type' |
| 41 | 43 | } | ... | ... |
yudao-admin-ui/src/views/bpm/definition/index.vue
| ... | ... | @@ -29,7 +29,7 @@ |
| 29 | 29 | <el-tag size="medium" type="warning" v-else>未部署</el-tag> |
| 30 | 30 | </template> |
| 31 | 31 | </el-table-column> |
| 32 | - <el-table-column label="激活状态" align="center" prop="version" width="80"> | |
| 32 | + <el-table-column label="状态" align="center" prop="version" width="80"> | |
| 33 | 33 | <template slot-scope="scope"> |
| 34 | 34 | <el-tag type="success" v-if="scope.row.suspensionState === 1">激活</el-tag> |
| 35 | 35 | <el-tag type="warning" v-if="scope.row.suspensionState === 2">挂起</el-tag> | ... | ... |
yudao-admin-ui/src/views/bpm/model/modelEditor.vue
| ... | ... | @@ -175,17 +175,8 @@ export default { |
| 175 | 175 | |
| 176 | 176 | .my-process-designer { |
| 177 | 177 | height: calc(100vh - 84px); |
| 178 | - //height: 800px !important; // TODO 芋艿:bjs 容器的高度不对,临时改下 | |
| 179 | - //z-index: 0 !important; | |
| 180 | - //pointer-events: none !important; | |
| 181 | 178 | } |
| 182 | -.process-panel__container { // TODO 芋艿:右边的位置不对,临时改下 | |
| 183 | - //margin-top: -800px !important; | |
| 184 | - //float: right; | |
| 185 | - //margin-left: 800px !important; | |
| 186 | - //height: 800px; | |
| 187 | - //z-index: 2147483647 !important; | |
| 188 | - //cursor:pointer !important; | |
| 179 | +.process-panel__container { | |
| 189 | 180 | position: absolute; |
| 190 | 181 | right: 0; |
| 191 | 182 | top: 55px; | ... | ... |
yudao-admin-ui/src/views/bpm/processInstance/create.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="app-container"> | |
| 3 | + <!-- 第一步,通过流程定义的列表,选择对应的流程 --> | |
| 4 | + <div v-if="!selectProcessInstance"> | |
| 5 | + <el-table v-loading="loading" :data="list"> | |
| 6 | + <el-table-column label="流程名称" align="center" prop="name" width="200"> | |
| 7 | + <template slot-scope="scope"> | |
| 8 | + <el-button type="text" @click="handleBpmnDetail(scope.row)"> | |
| 9 | + <span>{{ scope.row.name }}</span> | |
| 10 | + </el-button> | |
| 11 | + </template> | |
| 12 | + </el-table-column> | |
| 13 | + <el-table-column label="流程分类" align="center" prop="category" width="100"> | |
| 14 | + <template slot-scope="scope"> | |
| 15 | + <span>{{ getDictDataLabel(DICT_TYPE.BPM_MODEL_CATEGORY, scope.row.category) }}</span> | |
| 16 | + </template> | |
| 17 | + </el-table-column> | |
| 18 | + <el-table-column label="流程版本" align="center" prop="processDefinition.version" width="80"> | |
| 19 | + <template slot-scope="scope"> | |
| 20 | + <el-tag size="medium" v-if="scope.row">v{{ scope.row.version }}</el-tag> | |
| 21 | + </template> | |
| 22 | + </el-table-column> | |
| 23 | + <el-table-column label="流程描述" align="center" prop="description" width="300" show-overflow-tooltip /> | |
| 24 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 25 | + <template slot-scope="scope"> | |
| 26 | + <el-button type="text" size="small" icon="el-icon-plus" @click="handleSelect(scope.row)">选择</el-button> | |
| 27 | + </template> | |
| 28 | + </el-table-column> | |
| 29 | + </el-table> | |
| 30 | + </div> | |
| 31 | + <!-- 第二步,填写表单,进行流程的提交 --> | |
| 32 | + <div v-else> | |
| 33 | + <el-card class="box-card" > | |
| 34 | + <div slot="header" class="clearfix"> | |
| 35 | + <span class="el-icon-document">{{ selectProcessInstance.name }}</span> | |
| 36 | + <el-button style="float: right;" type="primary" @click="selectProcessInstance = undefined">选择其它流程</el-button> | |
| 37 | + </div> | |
| 38 | + <el-col :span="16" :offset="6"> | |
| 39 | + <div> | |
| 40 | + <parser :key="new Date().getTime()" :form-conf="detailForm" @submit="submitForm" /> | |
| 41 | + </div> | |
| 42 | + </el-col> | |
| 43 | + </el-card> | |
| 44 | + <el-card class="box-card"> | |
| 45 | + <div slot="header" class="clearfix"> | |
| 46 | + <span class="el-icon-picture-outline">流程图</span> | |
| 47 | + </div> | |
| 48 | + <my-process-viewer key="designer" v-model="bpmnXML" v-bind="bpmnControlForm" /> | |
| 49 | + </el-card> | |
| 50 | + </div> | |
| 51 | + | |
| 52 | + </div> | |
| 53 | +</template> | |
| 54 | + | |
| 55 | +<script> | |
| 56 | +import {getProcessDefinitionBpmnXML, getProcessDefinitionList} from "@/api/bpm/definition"; | |
| 57 | +import {DICT_TYPE, getDictDatas} from "@/utils/dict"; | |
| 58 | +import {getForm} from "@/api/bpm/form"; | |
| 59 | +import {decodeFields} from "@/utils/formGenerator"; | |
| 60 | +import Parser from '@/components/parser/Parser' | |
| 61 | +import {createProcessInstance} from "@/api/bpm/processInstance"; | |
| 62 | + | |
| 63 | +export default { | |
| 64 | + name: "processDefinition", | |
| 65 | + components: { | |
| 66 | + Parser | |
| 67 | + }, | |
| 68 | + data() { | |
| 69 | + return { | |
| 70 | + // 遮罩层 | |
| 71 | + loading: true, | |
| 72 | + // 总条数 | |
| 73 | + total: 0, | |
| 74 | + // 表格数据 | |
| 75 | + list: [], | |
| 76 | + | |
| 77 | + // 流程表单详情 | |
| 78 | + detailForm: { | |
| 79 | + fields: [] | |
| 80 | + }, | |
| 81 | + | |
| 82 | + // BPMN 数据 | |
| 83 | + bpmnXML: null, | |
| 84 | + bpmnControlForm: { | |
| 85 | + prefix: "activiti" | |
| 86 | + }, | |
| 87 | + | |
| 88 | + // 流程表单 | |
| 89 | + selectProcessInstance: undefined, // 选择的流程实例 | |
| 90 | + | |
| 91 | + // 数据字典 | |
| 92 | + categoryDictDatas: getDictDatas(DICT_TYPE.BPM_MODEL_CATEGORY), | |
| 93 | + }; | |
| 94 | + }, | |
| 95 | + created() { | |
| 96 | + this.getList(); | |
| 97 | + }, | |
| 98 | + methods: { | |
| 99 | + /** 查询流程定义列表 */ | |
| 100 | + getList() { | |
| 101 | + this.loading = true; | |
| 102 | + getProcessDefinitionList({ | |
| 103 | + suspensionState: 1 | |
| 104 | + }).then(response => { | |
| 105 | + this.list = response.data | |
| 106 | + this.loading = false | |
| 107 | + } | |
| 108 | + ); | |
| 109 | + }, | |
| 110 | + /** 处理选择流程的按钮操作 **/ | |
| 111 | + handleSelect(row) { | |
| 112 | + // 如果无表单,则无法发起流程 | |
| 113 | + if (!row.formId) { | |
| 114 | + this.$message.error('该流程未绑定表单,无法发起流程!请重新选择你要发起的流程'); | |
| 115 | + return; | |
| 116 | + } | |
| 117 | + // 设置选择的流程 | |
| 118 | + this.selectProcessInstance = row; | |
| 119 | + | |
| 120 | + // 加载对应的表单 | |
| 121 | + getForm(row.formId).then(response => { | |
| 122 | + // 设置值 | |
| 123 | + const data = response.data | |
| 124 | + this.detailForm = { | |
| 125 | + ...JSON.parse(data.conf), | |
| 126 | + fields: decodeFields(data.fields) | |
| 127 | + } | |
| 128 | + }); | |
| 129 | + | |
| 130 | + // 加载流程图 | |
| 131 | + getProcessDefinitionBpmnXML(row.id).then(response => { | |
| 132 | + this.bpmnXML = response.data | |
| 133 | + }) | |
| 134 | + }, | |
| 135 | + /** 提交按钮 */ | |
| 136 | + submitForm(params) { | |
| 137 | + if (!params) { | |
| 138 | + return; | |
| 139 | + } | |
| 140 | + // 设置表单禁用 | |
| 141 | + const conf = params.conf; | |
| 142 | + conf.disabled = true; // 表单禁用 | |
| 143 | + conf.formBtns = false; // 按钮隐藏 | |
| 144 | + | |
| 145 | + // 提交表单,创建流程 | |
| 146 | + const variables = params.values; | |
| 147 | + createProcessInstance({ | |
| 148 | + processDefinitionId: this.selectProcessInstance.id, | |
| 149 | + variables: variables | |
| 150 | + }).then(response => { | |
| 151 | + this.msgSuccess("发起流程成功"); | |
| 152 | + // 关闭当前窗口 | |
| 153 | + this.$store.dispatch("tagsView/delView", this.$route); | |
| 154 | + this.$router.go(-1); | |
| 155 | + }).catch(() => { | |
| 156 | + conf.disabled = false; // 表单开启 | |
| 157 | + conf.formBtns = true; // 按钮展示 | |
| 158 | + }) | |
| 159 | + }, | |
| 160 | + } | |
| 161 | +}; | |
| 162 | +</script> | |
| 163 | + | |
| 164 | +<style lang="scss"> | |
| 165 | +.my-process-designer { | |
| 166 | + height: calc(100vh - 200px); | |
| 167 | +} | |
| 168 | + | |
| 169 | +.box-card { | |
| 170 | + width: 100%; | |
| 171 | + margin-bottom: 20px; | |
| 172 | +} | |
| 173 | +</style> | ... | ... |
yudao-admin-ui/src/views/bpm/processInstance/index.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="app-container"> | |
| 3 | + | |
| 4 | + <!-- 搜索工作栏 --> | |
| 5 | + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> | |
| 6 | + <el-form-item label="流程名" prop="name"> | |
| 7 | + <el-input v-model="queryParams.name" placeholder="请输入流程名" clearable size="small" @keyup.enter.native="handleQuery"/> | |
| 8 | + </el-form-item> | |
| 9 | + <el-form-item label="所属流程" prop="processDefinitionId"> | |
| 10 | + <el-input v-model="queryParams.processDefinitionId" placeholder="请输入流程定义的编号" clearable size="small" @keyup.enter.native="handleQuery"/> | |
| 11 | + </el-form-item> | |
| 12 | + <el-form-item label="流程分类" prop="category"> | |
| 13 | + <el-select v-model="queryParams.category" placeholder="请选择流程分类" clearable size="small"> | |
| 14 | + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.BPM_MODEL_CATEGORY)" | |
| 15 | + :key="dict.value" :label="dict.label" :value="dict.value"/> | |
| 16 | + </el-select> | |
| 17 | + </el-form-item> | |
| 18 | + <el-form-item label="提交时间"> | |
| 19 | + <el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" | |
| 20 | + type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" /> | |
| 21 | + </el-form-item> | |
| 22 | + <el-form-item label="状态" prop="status"> | |
| 23 | + <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small"> | |
| 24 | + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS)" | |
| 25 | + :key="dict.value" :label="dict.label" :value="dict.value"/> | |
| 26 | + </el-select> | |
| 27 | + </el-form-item> | |
| 28 | + <el-form-item label="结果" prop="result"> | |
| 29 | + <el-select v-model="queryParams.result" placeholder="请选择流结果" clearable size="small"> | |
| 30 | + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT)" | |
| 31 | + :key="dict.value" :label="dict.label" :value="dict.value"/> | |
| 32 | + </el-select> | |
| 33 | + </el-form-item> | |
| 34 | + <el-form-item> | |
| 35 | + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> | |
| 36 | + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |
| 37 | + </el-form-item> | |
| 38 | + </el-form> | |
| 39 | + | |
| 40 | + <!-- 操作工具栏 --> | |
| 41 | + <el-row :gutter="10" class="mb8"> | |
| 42 | + <el-col :span="1.5"> | |
| 43 | + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">发起流程</el-button> | |
| 44 | + </el-col> | |
| 45 | + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | |
| 46 | + </el-row> | |
| 47 | + | |
| 48 | + <!-- 列表 --> | |
| 49 | + <el-table v-loading="loading" :data="list"> | |
| 50 | + <el-table-column label="编号" align="center" prop="id" width="320" /> | |
| 51 | + <el-table-column label="流程名" align="center" prop="name" /> | |
| 52 | + <el-table-column label="流程分类" align="center" prop="category"> | |
| 53 | + <template slot-scope="scope"> | |
| 54 | + <span>{{ getDictDataLabel(DICT_TYPE.BPM_MODEL_CATEGORY, scope.row.category) }}</span> | |
| 55 | + </template> | |
| 56 | + </el-table-column> | |
| 57 | + <el-table-column label="当前审批任务" align="center" prop="tasks"> | |
| 58 | + <template slot-scope="scope"> | |
| 59 | + <el-button v-for="task in scope.row.tasks" type="text" @click="handleFormDetail(task.id)"> | |
| 60 | + <span>{{ task.name }}</span> | |
| 61 | + </el-button> | |
| 62 | + </template> | |
| 63 | + </el-table-column> | |
| 64 | + <el-table-column label="状态" align="center" prop="status"> | |
| 65 | + <template slot-scope="scope"> | |
| 66 | + <span> | |
| 67 | + <el-tag type="primary" v-if="scope.row.status === 1"> <!-- 进行中 --> | |
| 68 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, scope.row.status) }} | |
| 69 | + </el-tag> | |
| 70 | + <el-tag type="success" v-if="scope.row.status === 2"> <!-- 已结束 --> | |
| 71 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, scope.row.status) }} | |
| 72 | + </el-tag> | |
| 73 | + </span> | |
| 74 | + </template> | |
| 75 | + </el-table-column> | |
| 76 | + <el-table-column label="结果" align="center" prop="result"> | |
| 77 | + <template slot-scope="scope"> | |
| 78 | + <span> | |
| 79 | + <el-tag type="primary" v-if="scope.row.result === 1"> <!-- 进行中 --> | |
| 80 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, scope.row.result) }} | |
| 81 | + </el-tag> | |
| 82 | + <el-tag type="success" v-if="scope.row.result === 2"> <!-- 通过 --> | |
| 83 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, scope.row.result) }} | |
| 84 | + </el-tag> | |
| 85 | + <el-tag type="danger" v-if="scope.row.result === 3"> <!-- 不通过 --> | |
| 86 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, scope.row.result) }} | |
| 87 | + </el-tag> | |
| 88 | + <el-tag type="info" v-if="scope.row.result === 4"> <!-- 撤回 --> | |
| 89 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, scope.row.result) }} | |
| 90 | + </el-tag> | |
| 91 | + </span> | |
| 92 | + </template> | |
| 93 | + </el-table-column> | |
| 94 | + <el-table-column label="提交时间" align="center" prop="createTime" width="180"> | |
| 95 | + <template slot-scope="scope"> | |
| 96 | + <span>{{ parseTime(scope.row.createTime) }}</span> | |
| 97 | + </template> | |
| 98 | + </el-table-column> | |
| 99 | + <el-table-column label="结束时间" align="center" prop="createTime" width="180"> | |
| 100 | + <template slot-scope="scope"> | |
| 101 | + <span>{{ parseTime(scope.row.endTime) }}</span> | |
| 102 | + </template> | |
| 103 | + </el-table-column> | |
| 104 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 105 | + <template slot-scope="scope"> | |
| 106 | + <!-- TODO 芋艿:权限 --> | |
| 107 | + <el-button type="text" size="small" icon="el-icon-delete" v-if="scope.row.result === 1" | |
| 108 | + @click="handleCancel(scope.row)">取消</el-button> | |
| 109 | + </template> | |
| 110 | + </el-table-column> | |
| 111 | + </el-table> | |
| 112 | + <!-- 分页组件 --> | |
| 113 | + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | |
| 114 | + @pagination="getList"/> | |
| 115 | + | |
| 116 | + </div> | |
| 117 | +</template> | |
| 118 | + | |
| 119 | +<script> | |
| 120 | +import { | |
| 121 | + getMyProcessInstancePage, | |
| 122 | + createProcessInstanceExt, | |
| 123 | + updateProcessInstanceExt, | |
| 124 | + deleteProcessInstanceExt, | |
| 125 | + getProcessInstanceExt, | |
| 126 | + getProcessInstanceExtPage, | |
| 127 | + exportProcessInstanceExtExcel, cancelProcessInstance | |
| 128 | +} from "@/api/bpm/processInstance"; | |
| 129 | +import {deleteErrorCode} from "@/api/system/errorCode"; | |
| 130 | + | |
| 131 | +export default { | |
| 132 | + name: "ProcessInstanceExt", | |
| 133 | + components: { | |
| 134 | + }, | |
| 135 | + data() { | |
| 136 | + return { | |
| 137 | + // 遮罩层 | |
| 138 | + loading: true, | |
| 139 | + // 显示搜索条件 | |
| 140 | + showSearch: true, | |
| 141 | + // 总条数 | |
| 142 | + total: 0, | |
| 143 | + // 工作流的流程实例的拓展列表 | |
| 144 | + list: [], | |
| 145 | + // 是否显示弹出层 | |
| 146 | + dateRangeCreateTime: [], | |
| 147 | + // 查询参数 | |
| 148 | + queryParams: { | |
| 149 | + pageNo: 1, | |
| 150 | + pageSize: 10, | |
| 151 | + name: null, | |
| 152 | + processDefinitionId: null, | |
| 153 | + category: null, | |
| 154 | + status: null, | |
| 155 | + result: null, | |
| 156 | + } | |
| 157 | + }; | |
| 158 | + }, | |
| 159 | + created() { | |
| 160 | + this.getList(); | |
| 161 | + }, | |
| 162 | + methods: { | |
| 163 | + /** 查询列表 */ | |
| 164 | + getList() { | |
| 165 | + this.loading = true; | |
| 166 | + // 处理查询参数 | |
| 167 | + let params = {...this.queryParams}; | |
| 168 | + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); | |
| 169 | + // 执行查询 | |
| 170 | + getMyProcessInstancePage(params).then(response => { | |
| 171 | + this.list = response.data.list; | |
| 172 | + this.total = response.data.total; | |
| 173 | + this.loading = false; | |
| 174 | + }); | |
| 175 | + }, | |
| 176 | + /** 搜索按钮操作 */ | |
| 177 | + handleQuery() { | |
| 178 | + this.queryParams.pageNo = 1; | |
| 179 | + this.getList(); | |
| 180 | + }, | |
| 181 | + /** 重置按钮操作 */ | |
| 182 | + resetQuery() { | |
| 183 | + this.dateRangeCreateTime = []; | |
| 184 | + this.resetForm("queryForm"); | |
| 185 | + this.handleQuery(); | |
| 186 | + }, | |
| 187 | + /** 新增按钮操作 **/ | |
| 188 | + handleAdd() { | |
| 189 | + this.$router.push({ path: "/bpm/process-instance/create"}) | |
| 190 | + }, | |
| 191 | + /** 取消按钮操作 */ | |
| 192 | + handleCancel(row) { | |
| 193 | + const id = row.id; | |
| 194 | + this.$prompt('请输出取消原因?', "取消流程", { | |
| 195 | + type: 'warning', | |
| 196 | + confirmButtonText: "确定", | |
| 197 | + cancelButtonText: "取消", | |
| 198 | + inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/, // 判断非空,且非空格 | |
| 199 | + inputErrorMessage: "取消原因不能为空", | |
| 200 | + }).then(({ value }) => { | |
| 201 | + return cancelProcessInstance(id, value); | |
| 202 | + }).then(() => { | |
| 203 | + this.getList(); | |
| 204 | + this.msgSuccess("取消成功"); | |
| 205 | + }) | |
| 206 | + }, | |
| 207 | + } | |
| 208 | +}; | |
| 209 | +</script> | ... | ... |
yudao-admin-ui/src/views/bpm/task/done.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="app-container"> | |
| 3 | + | |
| 4 | + <!-- 搜索工作栏 --> | |
| 5 | + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> | |
| 6 | + <el-form-item label="流程名" prop="name"> | |
| 7 | + <el-input v-model="queryParams.name" placeholder="请输入流程名" clearable size="small" @keyup.enter.native="handleQuery"/> | |
| 8 | + </el-form-item> | |
| 9 | + <el-form-item label="创建时间"> | |
| 10 | + <el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" | |
| 11 | + type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" /> | |
| 12 | + </el-form-item> | |
| 13 | + <el-form-item> | |
| 14 | + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> | |
| 15 | + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |
| 16 | + </el-form-item> | |
| 17 | + </el-form> | |
| 18 | + | |
| 19 | + <!-- 列表 --> | |
| 20 | + <el-table v-loading="loading" :data="list"> | |
| 21 | + <el-table-column label="任务编号" align="center" prop="id" width="320" fixed /> | |
| 22 | + <el-table-column label="任务名称" align="center" prop="name" width="200" /> | |
| 23 | + <el-table-column label="所属流程" align="center" prop="processInstance.name" width="200" /> | |
| 24 | + <el-table-column label="流程发起人" align="center" prop="processInstance.startUserNickname" /> | |
| 25 | + <el-table-column label="结果" align="center" prop="result"> | |
| 26 | + <template slot-scope="scope"> | |
| 27 | + <span> | |
| 28 | + <el-tag type="primary" v-if="scope.row.result === 1"> <!-- 进行中 --> | |
| 29 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, scope.row.result) }} | |
| 30 | + </el-tag> | |
| 31 | + <el-tag type="success" v-if="scope.row.result === 2"> <!-- 通过 --> | |
| 32 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, scope.row.result) }} | |
| 33 | + </el-tag> | |
| 34 | + <el-tag type="danger" v-if="scope.row.result === 3"> <!-- 不通过 --> | |
| 35 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, scope.row.result) }} | |
| 36 | + </el-tag> | |
| 37 | + <el-tag type="info" v-if="scope.row.result === 4"> <!-- 撤回 --> | |
| 38 | + {{ getDictDataLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, scope.row.result) }} | |
| 39 | + </el-tag> | |
| 40 | + </span> | |
| 41 | + </template> | |
| 42 | + </el-table-column> | |
| 43 | + <el-table-column label="审批意见" align="center" prop="comment" width="200" /> | |
| 44 | + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | |
| 45 | + <template slot-scope="scope"> | |
| 46 | + <span>{{ parseTime(scope.row.createTime) }}</span> | |
| 47 | + </template> | |
| 48 | + </el-table-column> | |
| 49 | + <el-table-column label="审批时间" align="center" prop="endTime" width="180"> | |
| 50 | + <template slot-scope="scope"> | |
| 51 | + <span>{{ parseTime(scope.row.endTime) }}</span> | |
| 52 | + </template> | |
| 53 | + </el-table-column> | |
| 54 | + <el-table-column label="耗时" align="center" prop="durationInMillis" width="180"> | |
| 55 | + <template slot-scope="scope"> | |
| 56 | + <span>{{ getDateStar(scope.row.durationInMillis) }}</span> | |
| 57 | + </template> | |
| 58 | + </el-table-column> | |
| 59 | + <!-- TODO 耗时 --> | |
| 60 | + <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width"> | |
| 61 | + <template slot-scope="scope"> | |
| 62 | + <!-- TODO 权限、颜色 --> | |
| 63 | + <el-button size="mini" type="text" icon="el-icon-edit">详情</el-button> | |
| 64 | + </template> | |
| 65 | + </el-table-column> | |
| 66 | + </el-table> | |
| 67 | + <!-- 分页组件 --> | |
| 68 | + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | |
| 69 | + @pagination="getList"/> | |
| 70 | + | |
| 71 | + </div> | |
| 72 | +</template> | |
| 73 | + | |
| 74 | +<script> | |
| 75 | +import {getDoneTaskPage} from '@/api/bpm/task' | |
| 76 | +import {getDate} from "@/utils/dateUtils"; | |
| 77 | + | |
| 78 | +export default { | |
| 79 | + name: "Done", | |
| 80 | + components: { | |
| 81 | + }, | |
| 82 | + data() { | |
| 83 | + return { | |
| 84 | + // 遮罩层 | |
| 85 | + loading: true, | |
| 86 | + // 显示搜索条件 | |
| 87 | + showSearch: true, | |
| 88 | + // 总条数 | |
| 89 | + total: 0, | |
| 90 | + // 待办任务列表 | |
| 91 | + list: [], | |
| 92 | + // 查询参数 | |
| 93 | + dateRangeCreateTime: [], | |
| 94 | + queryParams: { | |
| 95 | + pageNo: 1, | |
| 96 | + pageSize: 10, | |
| 97 | + name: null, | |
| 98 | + }, | |
| 99 | + }; | |
| 100 | + }, | |
| 101 | + created() { | |
| 102 | + this.getList(); | |
| 103 | + }, | |
| 104 | + methods: { | |
| 105 | + /** 查询列表 */ | |
| 106 | + getList() { | |
| 107 | + this.loading = true; | |
| 108 | + // 处理查询参数 | |
| 109 | + let params = {...this.queryParams}; | |
| 110 | + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); | |
| 111 | + getDoneTaskPage(params).then(response => { | |
| 112 | + this.list = response.data.list; | |
| 113 | + this.total = response.data.total; | |
| 114 | + this.loading = false; | |
| 115 | + }); | |
| 116 | + }, | |
| 117 | + /** 搜索按钮操作 */ | |
| 118 | + handleQuery() { | |
| 119 | + this.queryParams.pageNo = 1; | |
| 120 | + this.getList(); | |
| 121 | + }, | |
| 122 | + /** 重置按钮操作 */ | |
| 123 | + resetQuery() { | |
| 124 | + this.dateRangeCreateTime = []; | |
| 125 | + this.resetForm("queryForm"); | |
| 126 | + this.handleQuery(); | |
| 127 | + }, | |
| 128 | + getDateStar(ms) { | |
| 129 | + return getDate(ms); | |
| 130 | + } | |
| 131 | + } | |
| 132 | +}; | |
| 133 | +</script> | ... | ... |
yudao-admin-ui/src/views/bpm/task/todo.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="app-container"> | |
| 3 | + | |
| 4 | + <!-- 搜索工作栏 --> | |
| 5 | + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> | |
| 6 | + <el-form-item label="流程名" prop="name"> | |
| 7 | + <el-input v-model="queryParams.name" placeholder="请输入流程名" clearable size="small" @keyup.enter.native="handleQuery"/> | |
| 8 | + </el-form-item> | |
| 9 | + <el-form-item label="创建时间"> | |
| 10 | + <el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" | |
| 11 | + type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" /> | |
| 12 | + </el-form-item> | |
| 13 | + <el-form-item> | |
| 14 | + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> | |
| 15 | + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |
| 16 | + </el-form-item> | |
| 17 | + </el-form> | |
| 18 | + | |
| 19 | + <!-- 列表 --> | |
| 20 | + <el-table v-loading="loading" :data="list"> | |
| 21 | + <el-table-column label="任务编号" align="center" prop="id" width="320" /> | |
| 22 | + <el-table-column label="任务名称" align="center" prop="name" /> | |
| 23 | + <el-table-column label="所属流程" align="center" prop="processInstance.name" /> | |
| 24 | + <el-table-column label="流程发起人" align="center" prop="processInstance.startUserNickname" /> | |
| 25 | + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | |
| 26 | + <template slot-scope="scope"> | |
| 27 | + <span>{{ parseTime(scope.row.createTime) }}</span> | |
| 28 | + </template> | |
| 29 | + </el-table-column> | |
| 30 | + <el-table-column label="状态" align="center" prop="version" width="80"> | |
| 31 | + <template slot-scope="scope"> | |
| 32 | + <el-tag type="success" v-if="scope.row.suspensionState === 1">激活</el-tag> | |
| 33 | + <el-tag type="warning" v-if="scope.row.suspensionState === 2">挂起</el-tag> | |
| 34 | + </template> | |
| 35 | + </el-table-column> | |
| 36 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 37 | + <template slot-scope="scope"> | |
| 38 | + <!-- TODO 权限、颜色 --> | |
| 39 | + <el-button size="mini" type="text" icon="el-icon-edit">审批</el-button> | |
| 40 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="audit(scope.row, true)">通过</el-button> | |
| 41 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="audit(scope.row, false)">不通过</el-button> | |
| 42 | + <el-button size="mini" type="text" icon="el-icon-edit" v-if="scope.row.suspensionState === 2">激活</el-button> | |
| 43 | + <el-button size="mini" type="text" icon="el-icon-edit" v-if="scope.row.suspensionState === 1">挂起</el-button> | |
| 44 | + </template> | |
| 45 | + </el-table-column> | |
| 46 | + </el-table> | |
| 47 | + <!-- 分页组件 --> | |
| 48 | + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | |
| 49 | + @pagination="getList"/> | |
| 50 | + | |
| 51 | + </div> | |
| 52 | +</template> | |
| 53 | + | |
| 54 | +<script> | |
| 55 | +import {approveTask, getTodoTaskPage, rejectTask} from '@/api/bpm/task' | |
| 56 | + | |
| 57 | +export default { | |
| 58 | + name: "Todo", | |
| 59 | + components: { | |
| 60 | + }, | |
| 61 | + data() { | |
| 62 | + return { | |
| 63 | + // 遮罩层 | |
| 64 | + loading: true, | |
| 65 | + // 显示搜索条件 | |
| 66 | + showSearch: true, | |
| 67 | + // 总条数 | |
| 68 | + total: 0, | |
| 69 | + // 待办任务列表 | |
| 70 | + list: [], | |
| 71 | + // 查询参数 | |
| 72 | + dateRangeCreateTime: [], | |
| 73 | + queryParams: { | |
| 74 | + pageNo: 1, | |
| 75 | + pageSize: 10, | |
| 76 | + name: null, | |
| 77 | + }, | |
| 78 | + }; | |
| 79 | + }, | |
| 80 | + created() { | |
| 81 | + this.getList(); | |
| 82 | + }, | |
| 83 | + methods: { | |
| 84 | + /** 查询列表 */ | |
| 85 | + getList() { | |
| 86 | + this.loading = true; | |
| 87 | + // 处理查询参数 | |
| 88 | + let params = {...this.queryParams}; | |
| 89 | + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); | |
| 90 | + getTodoTaskPage(params).then(response => { | |
| 91 | + this.list = response.data.list; | |
| 92 | + this.total = response.data.total; | |
| 93 | + this.loading = false; | |
| 94 | + }); | |
| 95 | + }, | |
| 96 | + /** 搜索按钮操作 */ | |
| 97 | + handleQuery() { | |
| 98 | + this.queryParams.pageNo = 1; | |
| 99 | + this.getList(); | |
| 100 | + }, | |
| 101 | + /** 重置按钮操作 */ | |
| 102 | + resetQuery() { | |
| 103 | + this.dateRangeCreateTime = []; | |
| 104 | + this.resetForm("queryForm"); | |
| 105 | + this.handleQuery(); | |
| 106 | + }, | |
| 107 | + audit(row, pass) { | |
| 108 | + if (pass) { | |
| 109 | + approveTask({ | |
| 110 | + id: row.id, | |
| 111 | + comment: '通过' | |
| 112 | + }) | |
| 113 | + } else { | |
| 114 | + rejectTask({ | |
| 115 | + id: row.id, | |
| 116 | + comment: '不通过' | |
| 117 | + }) | |
| 118 | + } | |
| 119 | + } | |
| 120 | + } | |
| 121 | +}; | |
| 122 | +</script> | ... | ... |
yudao-admin-ui/src/views/oa/todo/index.vue deleted
| 1 | -<template> | |
| 2 | - <div class="app-container"> | |
| 3 | - | |
| 4 | - <!-- 搜索工作栏 --> | |
| 5 | - <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> | |
| 6 | - <el-form-item label="状态" prop="status"> | |
| 7 | - <el-select v-model="queryParams.status" placeholder="请选择状态"> | |
| 8 | - <el-option | |
| 9 | - v-for="dict in leaveStatusData" | |
| 10 | - :key="parseInt(dict.value)" | |
| 11 | - :label="dict.label" | |
| 12 | - :value="parseInt(dict.value)" | |
| 13 | - /> | |
| 14 | - </el-select> | |
| 15 | - </el-form-item> | |
| 16 | - <el-form-item> | |
| 17 | - <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> | |
| 18 | - <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |
| 19 | - </el-form-item> | |
| 20 | - </el-form> | |
| 21 | - | |
| 22 | - | |
| 23 | - | |
| 24 | - <!-- 列表 --> | |
| 25 | - <el-table v-loading="loading" :data="list"> | |
| 26 | - <el-table-column label="任务Id" align="center" prop="id" /> | |
| 27 | - <el-table-column label="流程名称" align="center" prop="processName" /> | |
| 28 | - <el-table-column label="任务状态" align="center" :formatter="statusFormat" prop="status" /> | |
| 29 | - <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 30 | - <template slot-scope="scope"> | |
| 31 | - <el-button size="mini" type="text" icon="el-icon-edit" v-if="scope.row.status == 1" @click="handleClaim(scope.row)">签收</el-button> | |
| 32 | - <el-button size="mini" type="text" icon="el-icon-edit" v-if="scope.row.status == 2" @click="getTaskFormKey(scope.row)">办理</el-button> | |
| 33 | - </template> | |
| 34 | - </el-table-column> | |
| 35 | - </el-table> | |
| 36 | - <!-- 分页组件 --> | |
| 37 | - <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | |
| 38 | - @pagination="getList"/> | |
| 39 | - | |
| 40 | - <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body> | |
| 41 | - <el-tabs tab-position="left" style="height: 500px;"> | |
| 42 | - <el-tab-pane label="详情"> | |
| 43 | - <el-form ref="form" :model="handleTask.formObject" label-width="80px"> | |
| 44 | - <el-form-item label="状态" > | |
| 45 | - {{ getDictDataLabel(DICT_TYPE.OA_LEAVE_STATUS, handleTask.formObject.status) }} | |
| 46 | - </el-form-item> | |
| 47 | - <el-form-item label="申请人id" >{{handleTask.formObject.userId}}</el-form-item> | |
| 48 | - <el-form-item label="开始时间" >{{ parseTime(handleTask.formObject.startTime) }}</el-form-item> | |
| 49 | - <el-form-item label="结束时间" prop="endTime">{{ parseTime(handleTask.formObject.endTime) }}</el-form-item> | |
| 50 | - <el-form-item label="请假类型" prop="leaveType"> | |
| 51 | - {{ getDictDataLabel(DICT_TYPE.OA_LEAVE_TYPE, handleTask.formObject.leaveType) }} | |
| 52 | - </el-form-item> | |
| 53 | - <el-form-item label="原因" prop="reason">{{handleTask.formObject.reason}}</el-form-item> | |
| 54 | - <el-form-item label="申请时间" prop="applyTime">{{ parseTime(handleTask.formObject.applyTime) }}</el-form-item> | |
| 55 | - </el-form> | |
| 56 | - </el-tab-pane> | |
| 57 | - <el-tab-pane label="任务处理"> | |
| 58 | - <el-steps :active="handleTask.historyTask.length-1" simple finish-status="success"> | |
| 59 | - <el-step :title="item.stepName" icon="el-icon-edit" v-for="(item) in handleTask.historyTask" ></el-step> | |
| 60 | - </el-steps> | |
| 61 | - <br/> | |
| 62 | - <el-steps direction="vertical" :active="handleTask.historyTask.length-1" finish-status="success" space="60px"> | |
| 63 | - <el-step :title="item.stepName" :description="item.comment" v-for="(item) in handleTask.historyTask" ></el-step> | |
| 64 | - </el-steps> | |
| 65 | - <br/> | |
| 66 | - <el-form ref="taskForm" :model="task" label-width="80px" v-show="handleTask.taskVariable !=''"> | |
| 67 | - <el-form-item label="处理意见" prop="approved"> | |
| 68 | - <el-select v-model="task.approved" placeholder="处理意见"> | |
| 69 | - <el-option | |
| 70 | - v-for="dict in approvedData" | |
| 71 | - :key="parseInt(dict.value)" | |
| 72 | - :label="dict.label" | |
| 73 | - :value="parseInt(dict.value)" | |
| 74 | - /> | |
| 75 | - </el-select> | |
| 76 | - </el-form-item> | |
| 77 | - <el-input | |
| 78 | - type="textarea" | |
| 79 | - :rows="2" | |
| 80 | - v-model="task.comment"> | |
| 81 | - </el-input> | |
| 82 | - </el-form> | |
| 83 | - <br/> | |
| 84 | - <el-button type="primary" @click="submitTask">提交</el-button> | |
| 85 | - </el-tab-pane> | |
| 86 | - </el-tabs> | |
| 87 | - </el-dialog> | |
| 88 | - </div> | |
| 89 | -</template> | |
| 90 | - | |
| 91 | -<script> | |
| 92 | -import { completeTask, taskSteps, getTaskFormKey,deleteLeave, getLeave, getTodoTaskPage, claimTask } from "@/api/oa/todo"; | |
| 93 | -import { getDictDataLabel, getDictDatas, DICT_TYPE } from '@/utils/dict' | |
| 94 | -export default { | |
| 95 | - name: "Todo", | |
| 96 | - components: { | |
| 97 | - }, | |
| 98 | - data() { | |
| 99 | - return { | |
| 100 | - // 遮罩层 | |
| 101 | - loading: true, | |
| 102 | - // 显示搜索条件 | |
| 103 | - showSearch: true, | |
| 104 | - // 总条数 | |
| 105 | - total: 0, | |
| 106 | - // 请假申请列表 | |
| 107 | - list: [], | |
| 108 | - // 弹出层标题 | |
| 109 | - title: "", | |
| 110 | - // 是否显示弹出层 | |
| 111 | - open: false, | |
| 112 | - // 查询参数 | |
| 113 | - queryParams: { | |
| 114 | - pageNo: 1, | |
| 115 | - pageSize: 10 | |
| 116 | - }, | |
| 117 | - // 表单参数 | |
| 118 | - form: {}, | |
| 119 | - handleTask: { | |
| 120 | - historyTask:[{ | |
| 121 | - stepName:"步骤一" | |
| 122 | - } | |
| 123 | - ], | |
| 124 | - taskVariable: "", | |
| 125 | - formObject: {} | |
| 126 | - }, | |
| 127 | - steps:[{ | |
| 128 | - stepName:"步骤一" | |
| 129 | - }], | |
| 130 | - task: { | |
| 131 | - approved : 1, | |
| 132 | - variables: {}, | |
| 133 | - taskId: undefined, | |
| 134 | - comment: "" | |
| 135 | - }, | |
| 136 | - rules: { | |
| 137 | - }, | |
| 138 | - leaveTypeDictData: getDictDatas(DICT_TYPE.OA_LEAVE_TYPE), | |
| 139 | - leaveStatusData: getDictDatas(DICT_TYPE.OA_LEAVE_STATUS), | |
| 140 | - approvedData: [ | |
| 141 | - { | |
| 142 | - value: 1, | |
| 143 | - label: '同意' | |
| 144 | - }, | |
| 145 | - { | |
| 146 | - value: 0, | |
| 147 | - label: '不同意' | |
| 148 | - } | |
| 149 | - ] | |
| 150 | - }; | |
| 151 | - }, | |
| 152 | - created() { | |
| 153 | - this.getList(); | |
| 154 | - }, | |
| 155 | - methods: { | |
| 156 | - /** 查询列表 */ | |
| 157 | - getList() { | |
| 158 | - this.loading = true; | |
| 159 | - // 处理查询参数 | |
| 160 | - let params = {...this.queryParams}; | |
| 161 | - // 执行查询 | |
| 162 | - getTodoTaskPage(params).then(response => { | |
| 163 | - this.list = response.data.list; | |
| 164 | - this.total = response.data.total; | |
| 165 | - this.loading = false; | |
| 166 | - }); | |
| 167 | - }, | |
| 168 | - /** 取消按钮 */ | |
| 169 | - cancel() { | |
| 170 | - this.open = false; | |
| 171 | - this.reset(); | |
| 172 | - }, | |
| 173 | - /** 表单重置 */ | |
| 174 | - reset() { | |
| 175 | - this.form = { | |
| 176 | - id: undefined, | |
| 177 | - processInstanceId: undefined, | |
| 178 | - status: undefined, | |
| 179 | - userId: undefined, | |
| 180 | - startTime: undefined, | |
| 181 | - endTime: undefined, | |
| 182 | - leaveType: undefined, | |
| 183 | - reason: undefined, | |
| 184 | - applyTime: undefined, | |
| 185 | - }; | |
| 186 | - this.resetForm("form"); | |
| 187 | - }, | |
| 188 | - | |
| 189 | - statusFormat(row, column) { | |
| 190 | - return row.status == 1 ? "未签收" : "已签收"; | |
| 191 | - }, | |
| 192 | - /** 搜索按钮操作 */ | |
| 193 | - handleQuery() { | |
| 194 | - this.queryParams.pageNo = 1; | |
| 195 | - this.getList(); | |
| 196 | - }, | |
| 197 | - /** 重置按钮操作 */ | |
| 198 | - resetQuery() { | |
| 199 | - this.dateRangeStartTime = []; | |
| 200 | - this.dateRangeEndTime = []; | |
| 201 | - this.dateRangeApplyTime = []; | |
| 202 | - this.resetForm("queryForm"); | |
| 203 | - this.handleQuery(); | |
| 204 | - }, | |
| 205 | - getTaskFormKey(row) { | |
| 206 | - const taskId = row.id; | |
| 207 | - const data = { | |
| 208 | - taskId : taskId | |
| 209 | - } | |
| 210 | - getTaskFormKey(data).then(response => { | |
| 211 | - const resp = response.data; | |
| 212 | - const path = resp.formKey; | |
| 213 | - const taskId = resp.id; | |
| 214 | - const businessKey = resp.businessKey; | |
| 215 | - const route = { | |
| 216 | - path: path, | |
| 217 | - query: { | |
| 218 | - businessKey: businessKey, | |
| 219 | - taskId:taskId, | |
| 220 | - processInstanceId : resp.processInstanceId | |
| 221 | - } | |
| 222 | - } | |
| 223 | - this.$router.replace(route); | |
| 224 | - }); | |
| 225 | - }, | |
| 226 | - handleLeaveApprove(row) { | |
| 227 | - this.reset(); | |
| 228 | - const businessKey = row.businessKey; | |
| 229 | - const taskId = row.id; | |
| 230 | - const processKey = row.processKey; | |
| 231 | - const data = { | |
| 232 | - taskId : taskId, | |
| 233 | - businessKey: businessKey, | |
| 234 | - processKey: processKey | |
| 235 | - } | |
| 236 | - taskSteps(data).then(response => { | |
| 237 | - this.form = {}; | |
| 238 | - this.handleTask = response.data; | |
| 239 | - this.task.taskId = taskId; | |
| 240 | - this.open = true; | |
| 241 | - this.title = "任务办理"; | |
| 242 | - }); | |
| 243 | - }, | |
| 244 | - /** 任务签收操作 */ | |
| 245 | - handleClaim(row) { | |
| 246 | - this.reset(); | |
| 247 | - const id = row.id; | |
| 248 | - claimTask(id).then(() => { | |
| 249 | - this.getList(); | |
| 250 | - this.msgSuccess("签收成功"); | |
| 251 | - }); | |
| 252 | - }, | |
| 253 | - /** 提交任务 */ | |
| 254 | - submitTask() { | |
| 255 | - const taskVariableName = this.handleTask.taskVariable; | |
| 256 | - if (taskVariableName != "") { | |
| 257 | - if (this.task.approved == 1) { | |
| 258 | - this.task.variables[taskVariableName] = true; | |
| 259 | - } | |
| 260 | - if (this.task.approved == 0) { | |
| 261 | - this.task.variables[taskVariableName] = false; | |
| 262 | - } | |
| 263 | - } | |
| 264 | - completeTask(this.task).then(response => { | |
| 265 | - this.msgSuccess("执行任务成功"); | |
| 266 | - this.open = false; | |
| 267 | - this.getList(); | |
| 268 | - }) | |
| 269 | - }, | |
| 270 | - /** 删除按钮操作 */ | |
| 271 | - handleDelete(row) { | |
| 272 | - const id = row.id; | |
| 273 | - this.$confirm('是否确认删除请假申请编号为"' + id + '"的数据项?', "警告", { | |
| 274 | - confirmButtonText: "确定", | |
| 275 | - cancelButtonText: "取消", | |
| 276 | - type: "warning" | |
| 277 | - }).then(function() { | |
| 278 | - return deleteLeave(id); | |
| 279 | - }).then(() => { | |
| 280 | - this.getList(); | |
| 281 | - this.msgSuccess("删除成功"); | |
| 282 | - }) | |
| 283 | - } | |
| 284 | - } | |
| 285 | -}; | |
| 286 | -</script> |
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java
| ... | ... | @@ -25,7 +25,9 @@ public interface WebFilterOrderEnum { |
| 25 | 25 | |
| 26 | 26 | // Spring Security Filter 默认为 -100,可见 org.springframework.boot.autoconfigure.security.SecurityProperties 配置属性类 |
| 27 | 27 | |
| 28 | - int TENANT_SECURITY_FILTER = -99; // 需要保证在 Spring Security 过滤器后 | |
| 28 | + int TENANT_SECURITY_FILTER = -99; // 需要保证在 Spring Security 过滤器后面 | |
| 29 | + | |
| 30 | + int ACTIVITI_FILTER = -98; // 需要保证在 Spring Security 过滤后面 | |
| 29 | 31 | |
| 30 | 32 | int DEMO_FILTER = Integer.MAX_VALUE; |
| 31 | 33 | ... | ... |
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java
yudao-framework/yudao-spring-boot-starter-activiti/pom.xml
| ... | ... | @@ -37,6 +37,14 @@ |
| 37 | 37 | <artifactId>yudao-common</artifactId> |
| 38 | 38 | </dependency> |
| 39 | 39 | |
| 40 | + <!-- Web 相关 --> | |
| 41 | + <dependency> | |
| 42 | + <groupId>cn.iocoder.boot</groupId> | |
| 43 | + <artifactId>yudao-spring-boot-starter-security</artifactId> | |
| 44 | + </dependency> | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 40 | 48 | <dependency> |
| 41 | 49 | <groupId>org.mybatis</groupId> |
| 42 | 50 | <artifactId>mybatis</artifactId> |
| ... | ... | @@ -72,6 +80,7 @@ |
| 72 | 80 | <artifactId>activiti-image-generator</artifactId> |
| 73 | 81 | <version>${activiti.version}</version> |
| 74 | 82 | </dependency> |
| 83 | + | |
| 75 | 84 | </dependencies> |
| 76 | 85 | |
| 77 | 86 | </project> | ... | ... |
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/config/YudaoActivitiConfiguration.java
| 1 | 1 | package cn.iocoder.yudao.framework.activiti.config; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.activiti.core.web.ActivitiWebFilter; | |
| 4 | +import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; | |
| 3 | 5 | import org.activiti.image.ProcessDiagramGenerator; |
| 4 | 6 | import org.activiti.image.impl.DefaultProcessDiagramGenerator; |
| 5 | 7 | import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer; |
| 6 | 8 | import org.apache.ibatis.session.SqlSessionFactory; |
| 9 | +import org.springframework.boot.web.servlet.FilterRegistrationBean; | |
| 7 | 10 | import org.springframework.context.annotation.Bean; |
| 8 | 11 | import org.springframework.context.annotation.Configuration; |
| 9 | 12 | |
| ... | ... | @@ -26,4 +29,12 @@ public class YudaoActivitiConfiguration { |
| 26 | 29 | return springProcessEngineConfiguration -> springProcessEngineConfiguration.setSqlSessionFactory(sqlSessionFactory); |
| 27 | 30 | } |
| 28 | 31 | |
| 32 | + @Bean | |
| 33 | + public FilterRegistrationBean<ActivitiWebFilter> activitiWebFilter() { | |
| 34 | + FilterRegistrationBean<ActivitiWebFilter> registrationBean = new FilterRegistrationBean<>(); | |
| 35 | + registrationBean.setFilter(new ActivitiWebFilter()); | |
| 36 | + registrationBean.setOrder(WebFilterOrderEnum.ACTIVITI_FILTER); | |
| 37 | + return registrationBean; | |
| 38 | + } | |
| 39 | + | |
| 29 | 40 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/util/ActivitiUtils.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.activiti.core.util; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.ReflectUtil; | |
| 4 | +import com.alibaba.ttl.TransmittableThreadLocal; | |
| 5 | +import org.activiti.engine.history.HistoricProcessInstance; | |
| 6 | +import org.activiti.engine.impl.identity.Authentication; | |
| 7 | +import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntityImpl; | |
| 8 | +import org.activiti.engine.impl.persistence.entity.HistoricScopeInstanceEntityImpl; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * Activiti 工具类 | |
| 12 | + * | |
| 13 | + * @author 芋道源码 | |
| 14 | + */ | |
| 15 | +public class ActivitiUtils { | |
| 16 | + | |
| 17 | + static { | |
| 18 | + setAuthenticationThreadLocal(); | |
| 19 | + } | |
| 20 | + | |
| 21 | + // ========== Authentication 相关 ========== | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * 反射修改 Authentication 的 authenticatedUserIdThreadLocal 静态变量,使用 TTL 线程变量 | |
| 25 | + * 目的:保证 @Async 等异步执行时,变量丢失的问题 | |
| 26 | + */ | |
| 27 | + private static void setAuthenticationThreadLocal() { | |
| 28 | + ReflectUtil.setFieldValue(Authentication.class, "authenticatedUserIdThreadLocal", | |
| 29 | + new TransmittableThreadLocal<String>()); | |
| 30 | + } | |
| 31 | + | |
| 32 | + public static void setAuthenticatedUserId(Long userId) { | |
| 33 | + Authentication.setAuthenticatedUserId(String.valueOf(userId)); | |
| 34 | + } | |
| 35 | + | |
| 36 | + public static void clearAuthenticatedUserId() { | |
| 37 | + Authentication.setAuthenticatedUserId(null); | |
| 38 | + } | |
| 39 | + | |
| 40 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/web/ActivitiWebFilter.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.activiti.core.web; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils; | |
| 4 | +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | |
| 5 | +import org.springframework.web.filter.OncePerRequestFilter; | |
| 6 | + | |
| 7 | +import javax.servlet.FilterChain; | |
| 8 | +import javax.servlet.ServletException; | |
| 9 | +import javax.servlet.http.HttpServletRequest; | |
| 10 | +import javax.servlet.http.HttpServletResponse; | |
| 11 | +import java.io.IOException; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * Activiti Web 过滤器,将 userId 设置到 {@link org.activiti.engine.impl.identity.Authentication} 中 | |
| 15 | + * | |
| 16 | + * @author 芋道源码 | |
| 17 | + */ | |
| 18 | +public class ActivitiWebFilter extends OncePerRequestFilter { | |
| 19 | + | |
| 20 | + @Override | |
| 21 | + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) | |
| 22 | + throws ServletException, IOException { | |
| 23 | + try { | |
| 24 | + // 设置工作流的用户 | |
| 25 | + Long userId = SecurityFrameworkUtils.getLoginUserId(); | |
| 26 | + if (userId != null) { | |
| 27 | + ActivitiUtils.setAuthenticatedUserId(userId); | |
| 28 | + } | |
| 29 | + // 过滤 | |
| 30 | + chain.doFilter(request, response); | |
| 31 | + } finally { | |
| 32 | + // 清理 | |
| 33 | + ActivitiUtils.clearAuthenticatedUserId(); | |
| 34 | + } | |
| 35 | + } | |
| 36 | + | |
| 37 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/dataobject/BaseDO.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.mybatis.core.dataobject; |
| 3 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; |
| 4 | 4 | import com.baomidou.mybatisplus.annotation.TableField; |
| 5 | 5 | import com.baomidou.mybatisplus.annotation.TableLogic; |
| 6 | +import lombok.Builder; | |
| 6 | 7 | import lombok.Data; |
| 7 | 8 | |
| 8 | 9 | import java.io.Serializable; | ... | ... |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
| ... | ... | @@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| 9 | 9 | import com.baomidou.mybatisplus.core.metadata.IPage; |
| 10 | 10 | import org.apache.ibatis.annotations.Param; |
| 11 | 11 | |
| 12 | +import java.util.Collection; | |
| 12 | 13 | import java.util.List; |
| 13 | 14 | |
| 14 | 15 | /** |
| ... | ... | @@ -44,4 +45,8 @@ public interface BaseMapperX<T> extends BaseMapper<T> { |
| 44 | 45 | return selectList(new QueryWrapper<T>().eq(field, value)); |
| 45 | 46 | } |
| 46 | 47 | |
| 48 | + default List<T> selectList(String field, Collection<?> values) { | |
| 49 | + return selectList(new QueryWrapper<T>().in(field, values)); | |
| 50 | + } | |
| 51 | + | |
| 47 | 52 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java
| ... | ... | @@ -98,15 +98,6 @@ public class SecurityFrameworkUtils { |
| 98 | 98 | // 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息 |
| 99 | 99 | WebFrameworkUtils.setLoginUserId(request, loginUser.getId()); |
| 100 | 100 | WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType()); |
| 101 | -// // TODO @jason:使用 userId 会不会更合适哈? | |
| 102 | -// // TODO @芋艿:activiti 需要使用 ttl 上下文 | |
| 103 | -// // TODO @jason:清理问题 | |
| 104 | -// if (Objects.equals(UserTypeEnum.ADMIN.getValue(), loginUser.getUserType())) { | |
| 105 | -// org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername()); | |
| 106 | -// } | |
| 107 | -// // TODO @芋道源码 该值被赋值给 user task 中assignee , username 显示更直白一点 | |
| 108 | -// // TODO @jason:有办法设置 userId,然后 activiti 有地方读取到 username 么?毕竟 username 只是 User 的登陆账号,并不能绝对像 userId 代表一个用户 | |
| 109 | -// org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername()); | |
| 110 | 101 | } |
| 111 | 102 | |
| 112 | 103 | } | ... | ... |
更新日志.md
| ... | ... | @@ -27,7 +27,11 @@ |
| 27 | 27 | ### ⭐ New Features |
| 28 | 28 | |
| 29 | 29 | * 【优化】引入 form generator 0.2.0 版本,并重构相关代码 |
| 30 | -* 【新增】新增流程表单,支持动态进行表单的配置 | |
| 30 | +* 【新增】流程表单,支持动态进行表单的配置 | |
| 31 | +* 【新增】流程模型的管理,支持新增、导入、编辑、删除、发布流程模型 | |
| 32 | +* 【新增】我的流程的管理,支持发起流程 | |
| 33 | +* 【新增】待办任务的管理,支持任务的审批通过与不通过 | |
| 34 | +* 【新增】已办任务的管理,支持详情的查看 | |
| 31 | 35 | * 【新增】引入 bpmn-process-designer 0.0.1 版本,提供流程设计器的能力 |
| 32 | 36 | |
| 33 | 37 | ### 🐞 Bug Fixes | ... | ... |