Commit 00f59fdc75b83c1e61e19cb7e810d62e81d0eee1

Authored by yunlong.li
1 parent 480b1750

fix: 完善 bpm 模型流程

yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/ModelController.java
1 1 package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow;
2 2  
3 3 import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.FileResp;
4 5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.TodoTaskRespVO;
5 6 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO;
  7 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelPageReqVo;
  8 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelRespVo;
6 9 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelUpdateVO;
7 10 import cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.BpmModelService;
8 11 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
9 12 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  13 +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
10 14 import com.fasterxml.jackson.databind.ObjectMapper;
11 15 import com.fasterxml.jackson.databind.node.ObjectNode;
12 16 import io.swagger.annotations.Api;
  17 +import io.swagger.annotations.ApiOperation;
13 18 import lombok.RequiredArgsConstructor;
14 19 import lombok.extern.slf4j.Slf4j;
15 20 import org.activiti.engine.*;
... ... @@ -36,18 +41,41 @@ public class ModelController {
36 41  
37 42 private final BpmModelService bpmModelService;
38 43  
  44 + @GetMapping ("/page")
  45 + @ApiOperation(value = "分页数据")
  46 + public PageResult<Model> pageList(ModelPageReqVo modelPageReqVo) {
  47 + return bpmModelService.pageList(modelPageReqVo);
  48 + }
  49 +
39 50 @PostMapping("/create")
  51 + @ApiOperation(value = "新建模型")
40 52 public CommonResult<String> newModel(@RequestBody ModelCreateVO modelCreateVO) {
41 53 return bpmModelService.newModel(modelCreateVO);
42 54 }
43 55  
44 56 @PostMapping("/update")
  57 + @ApiOperation(value = "修改模型属性")
45 58 public CommonResult<String> updateModel(@RequestBody ModelUpdateVO modelUpdateVO) {
46 59 return bpmModelService.updateModel(modelUpdateVO);
47 60 }
48 61  
49   - @PostMapping("/deploy/{modelId}")
50   - public CommonResult<String> updateModel(@PathVariable String modelId) {
  62 + @PostMapping("/delete")
  63 + @ApiOperation(value = "删除模型")
  64 + public CommonResult<String> deleteModel(@RequestParam String modelId) {
  65 + return bpmModelService.deleteModel(modelId);
  66 + }
  67 +
  68 + @PostMapping("/deploy")
  69 + @ApiOperation(value = "部署模型")
  70 + public CommonResult<String> deploy(@RequestParam String modelId) {
51 71 return bpmModelService.deploy(modelId);
52 72 }
  73 +
  74 + @GetMapping("/exportBpmnXml")
  75 + @ApiOperation(value = "导出模型")
  76 + public void export(@RequestParam String deploymentId, HttpServletResponse response) throws IOException {
  77 + FileResp fileResp = bpmModelService.exportBpmnXml(deploymentId);
  78 + ServletUtils.writeAttachment(response, fileResp.getFileName(), fileResp.getFileByte());
  79 + }
  80 +
53 81 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/TaskController.java
... ... @@ -60,13 +60,12 @@ public class TaskController {
60 60 return success(bpmTaskService.getHistorySteps(processInstanceId));
61 61 }
62 62  
63   - // TODO @Li: 项目里,暂时不使用 path 路径参数,监控等麻烦
64 63 /**
65 64 * 返回高亮的流转图SVG
66   - * @param processInstanceId
  65 + * @param processInstanceId 流程Id
67 66 */
68   - @GetMapping("/process/highlight-img/{id}")
69   - public void getHighlightImg(@PathVariable("id") String processInstanceId, HttpServletResponse response) throws IOException {
  67 + @GetMapping("/process/highlight-img")
  68 + public void getHighlightImg(@RequestParam String processInstanceId, HttpServletResponse response) throws IOException {
70 69 FileResp fileResp = bpmTaskService.getHighlightImg(processInstanceId);
71 70 ServletUtils.writeAttachment(response, fileResp.getFileName(), fileResp.getFileByte());
72 71 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelPageReqVo.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.annotations.ApiModel;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.ToString;
  9 +
  10 +/**
  11 + * @author yunlong.li
  12 + */
  13 +@ApiModel("模型分页 Request VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +public class ModelPageReqVo extends PageParam {
  18 + @ApiModelProperty("模型名字")
  19 + private String name;
  20 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelRespVo.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.annotations.ApiModel;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +/**
  10 + * @author yunlong.li
  11 + */
  12 +@ApiModel("模型出口内容 Request VO")
  13 +@Data
  14 +@ToString(callSuper = true)
  15 +public class ModelRespVo {
  16 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/workflow/ModelConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.convert.workflow;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.TodoTaskRespVO;
  4 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelRespVo;
  5 +import org.activiti.api.task.model.Task;
  6 +import org.activiti.engine.repository.Model;
  7 +import org.activiti.engine.repository.ProcessDefinition;
  8 +import org.mapstruct.Mapper;
  9 +import org.mapstruct.factory.Mappers;
  10 +
  11 +
  12 +/**
  13 + * @author yunlongn
  14 + */
  15 +@Mapper
  16 +public interface ModelConvert {
  17 + ModelConvert INSTANCE = Mappers.getMapper(ModelConvert.class);
  18 +
  19 + ModelRespVo convert(Model model);
  20 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java
... ... @@ -28,5 +28,6 @@ public interface BpmErrorCodeConstants {
28 28 ErrorCode BPMN_MODEL_EDITOR_SOURCE_NOT_EXISTS = new ErrorCode(1004001001, "模型数据为空,请先成功设计流程并保存");
29 29 ErrorCode BPMN_MODEL_ERROR = new ErrorCode(1004001002, "工作流模型异常");
30 30 ErrorCode BPMN_MODEL_PROCESS_NOT_EXISTS = new ErrorCode(1004001003, "流程数据为空");
  31 + ErrorCode BPMN_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1004001004, "流程定义不存在");
31 32  
32 33 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/BpmModelService.java
1 1 package cn.iocoder.yudao.adminserver.modules.bpm.service.workflow;
2 2  
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.FileResp;
3 4 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO;
  5 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelPageReqVo;
  6 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelRespVo;
4 7 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelUpdateVO;
5 8 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  9 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  10 +import org.activiti.engine.repository.Model;
  11 +
  12 +import javax.servlet.http.HttpServletResponse;
6 13  
7 14 /**
8 15 * 工作流模型接口
... ... @@ -10,16 +17,45 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
10 17 */
11 18 public interface BpmModelService {
12 19  
  20 +
  21 + /**
  22 + * 模型数据分页返回
  23 + * @param modelPageReqVo 分页入参
  24 + * @return 分页model
  25 + */
  26 + PageResult<Model> pageList(ModelPageReqVo modelPageReqVo);
  27 +
13 28 /**
14 29 * 新增一个模型
15 30 * @param modelCreateVO 模型对象
16 31 * @return 返回成功
17 32 */
18 33 CommonResult<String> newModel(ModelCreateVO modelCreateVO);
19   -
  34 + /**
  35 + * 修改模型属性,填充bpmn数据
  36 + * @param modelUpdateVO 模型对象
  37 + * @return 返回成功
  38 + */
20 39 CommonResult<String> updateModel(ModelUpdateVO modelUpdateVO);
21 40  
  41 + /**
  42 + * 部署模型 使模型成为一个 process
  43 + * @param modelId 模型Id
  44 + * @return 返回成功
  45 + */
22 46 CommonResult<String> deploy(String modelId);
23 47  
  48 + /**
  49 + * 导出模型
  50 + * @param modelId 模型Id
  51 + * @return {@link FileResp} 返回文件
  52 + */
  53 + FileResp exportBpmnXml(String modelId);
24 54  
  55 + /**
  56 + * 删除模型
  57 + * @param modelId 模型Id
  58 + * @return 返回成功
  59 + */
  60 + CommonResult<String> deleteModel(String modelId);
25 61 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/BpmTaskService.java
... ... @@ -51,6 +51,7 @@ public interface BpmTaskService {
51 51 /**
52 52 * 返回高亮的流转进程
53 53 * @param processInstanceId 实例Id
  54 + * @return {@link FileResp} 返回文件
54 55 */
55 56 FileResp getHighlightImg(String processInstanceId);
56 57 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/impl/BpmModelServiceImpl.java
1 1 package cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.impl;
2 2  
  3 +import cn.hutool.core.io.IoUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.FileResp;
3 6 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO;
  7 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelPageReqVo;
  8 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelRespVo;
4 9 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelUpdateVO;
5 10 import cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants;
6 11 import cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.BpmModelService;
7 12 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
8 13 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  14 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 15 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
10 16 import lombok.RequiredArgsConstructor;
11 17 import lombok.extern.slf4j.Slf4j;
  18 +import org.activiti.api.runtime.shared.query.Pageable;
12 19 import org.activiti.bpmn.converter.BpmnXMLConverter;
13 20 import org.activiti.bpmn.model.BpmnModel;
14 21 import org.activiti.engine.RepositoryService;
15 22 import org.activiti.engine.repository.Deployment;
16 23 import org.activiti.engine.repository.Model;
  24 +import org.activiti.engine.repository.ModelQuery;
  25 +import org.activiti.engine.repository.ProcessDefinition;
17 26 import org.apache.commons.lang3.exception.ExceptionUtils;
18 27 import org.springframework.stereotype.Service;
19 28 import org.springframework.util.ObjectUtils;
20 29  
  30 +import javax.servlet.http.HttpServletResponse;
21 31 import javax.xml.stream.XMLInputFactory;
22 32 import javax.xml.stream.XMLStreamReader;
23 33 import java.io.ByteArrayInputStream;
  34 +import java.io.IOException;
  35 +import java.io.InputStream;
24 36 import java.io.InputStreamReader;
  37 +import java.net.URLEncoder;
25 38 import java.nio.charset.StandardCharsets;
  39 +import java.util.List;
26 40 import java.util.Optional;
27 41  
28 42 /**
... ... @@ -36,6 +50,19 @@ public class BpmModelServiceImpl implements BpmModelService {
36 50  
37 51 private final RepositoryService repositoryService;
38 52  
  53 +
  54 + @Override
  55 + public PageResult<Model> pageList(ModelPageReqVo modelPageReqVo) {
  56 + ModelQuery modelQuery = repositoryService.createModelQuery();
  57 + String likeName = modelPageReqVo.getName();
  58 + if (StrUtil.isNotBlank(likeName)){
  59 + modelQuery.modelNameLike("%"+likeName+"%");
  60 + }
  61 + List<Model> models = modelQuery.orderByCreateTime().desc()
  62 + .listPage((modelPageReqVo.getPageNo() - 1) * modelPageReqVo.getPageSize(), modelPageReqVo.getPageSize());
  63 + return new PageResult<>(models, modelQuery.count());
  64 + }
  65 +
39 66 @Override
40 67 public CommonResult<String> newModel(ModelCreateVO modelCreateVO) {
41 68 try {
... ... @@ -119,4 +146,28 @@ public class BpmModelServiceImpl implements BpmModelService {
119 146 throw ServiceExceptionUtil.exception(BpmErrorCodeConstants.BPMN_MODEL_ERROR);
120 147 }
121 148 }
  149 +
  150 + @Override
  151 + public FileResp exportBpmnXml(String deploymentId) {
  152 +
  153 + // 查询流程定义
  154 + ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
  155 + if (ObjectUtils.isEmpty(pd)) {
  156 + throw ServiceExceptionUtil.exception(BpmErrorCodeConstants.BPMN_PROCESS_DEFINITION_NOT_EXISTS);
  157 + }
  158 + String resourceName = Optional.ofNullable(pd.getDiagramResourceName()).orElse(pd.getResourceName());
  159 + InputStream inputStream = repositoryService.getResourceAsStream(deploymentId,
  160 + resourceName);
  161 + FileResp fileResp = new FileResp();
  162 +
  163 + fileResp.setFileName(String.format("%s.bpmn", Optional.ofNullable(pd.getName()).orElse("流程图")));
  164 + fileResp.setFileByte(IoUtil.readBytes(inputStream));
  165 + return fileResp;
  166 + }
  167 +
  168 + @Override
  169 + public CommonResult<String> deleteModel(String modelId) {
  170 + repositoryService.deleteModel(modelId);
  171 + return CommonResult.success("删除成功");
  172 + }
122 173 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/impl/BpmTaskServiceImpl.java
... ... @@ -31,6 +31,7 @@ import org.activiti.image.ProcessDiagramGenerator;
31 31 import org.apache.commons.lang3.exception.ExceptionUtils;
32 32 import org.springframework.stereotype.Service;
33 33 import org.springframework.transaction.annotation.Transactional;
  34 +import org.springframework.util.ObjectUtils;
34 35  
35 36 import javax.annotation.Resource;
36 37 import java.io.IOException;
... ... @@ -174,6 +175,18 @@ public class BpmTaskServiceImpl implements BpmTaskService {
174 175 if (hpi == null) {
175 176 throw exception(PROCESS_INSTANCE_NOT_EXISTS);
176 177 }
  178 + // 如果有结束时间 返回model的流程图
  179 + if (!ObjectUtils.isEmpty(hpi.getEndTime())) {
  180 + ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(hpi.getProcessDefinitionId()).singleResult();
  181 + String resourceName = Optional.ofNullable(pd.getDiagramResourceName()).orElse(pd.getResourceName());
  182 + BpmnModel bpmnModel = repositoryService.getBpmnModel(pd.getId());
  183 + InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, new ArrayList<>(1), new ArrayList<>(1),
  184 + "宋体", "宋体", "宋体");
  185 + FileResp fileResp = new FileResp();
  186 + fileResp.setFileName( resourceName + ".svg");
  187 + fileResp.setFileByte(IoUtil.readBytes(inputStream));
  188 + return fileResp;
  189 + }
177 190 // 没有结束时间。说明流程在执行过程中
178 191 // TODO @Li:一些 runtimeService 的查询,貌似比较通用,是不是抽一些小方法出来
179 192 ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
... ... @@ -195,13 +208,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
195 208 try (InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, highLightedActivities, highLightedFlowIds,
196 209 "宋体", "宋体", "宋体")){
197 210 FileResp fileResp = new FileResp();
198   - String picName = hpi.getProcessDefinitionName() + ".svg"; // TODO @Li:一次性的变量,可以直接 set 的时候,直接拼接
199   - fileResp.setFileName(picName);
  211 + fileResp.setFileName( hpi.getProcessDefinitionName() + ".svg");
200 212 fileResp.setFileByte(IoUtil.readBytes(inputStream));
201 213 return fileResp;
202 214 } catch (IOException e) {
203   - // TODO @Li:log.error("[getHighlightImg][流程({}) 生成图表失败]", processInstanceId, e)
204   - log.error(ExceptionUtils.getStackTrace(e));
  215 + log.error("[getHighlightImg][流程({}) 生成图表失败]", processInstanceId, e);
205 216 throw exception(HIGHLIGHT_IMG_ERROR);
206 217 }
207 218 }
... ...
yudao-admin-ui/src/api/oa/todo.js
... ... @@ -85,7 +85,7 @@ export function processHistorySteps(id) {
85 85  
86 86 export function getHighlightImg(id) {
87 87 return request({
88   - url: '/workflow/task/process/highlight-img/'+id,
  88 + url: '/workflow/task/process/highlight-img?processInstanceId='+id,
89 89 method: 'get'
90 90 })
91 91 }
... ...