Explorar el Código

fix: 完善 bpm 模型流程

yunlong.li hace 3 años
padre
commit
00f59fdc75

+ 30 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/ModelController.java

@@ -1,15 +1,20 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow;
 
 import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.FileResp;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.TodoTaskRespVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelPageReqVo;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelRespVo;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelUpdateVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.BpmModelService;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.activiti.engine.*;
@@ -36,18 +41,41 @@ public class ModelController {
 
     private final BpmModelService bpmModelService;
 
+    @GetMapping ("/page")
+    @ApiOperation(value = "分页数据")
+    public PageResult<Model> pageList(ModelPageReqVo modelPageReqVo) {
+       return bpmModelService.pageList(modelPageReqVo);
+    }
+
     @PostMapping("/create")
+    @ApiOperation(value = "新建模型")
     public CommonResult<String> newModel(@RequestBody ModelCreateVO modelCreateVO) {
        return bpmModelService.newModel(modelCreateVO);
     }
 
     @PostMapping("/update")
+    @ApiOperation(value = "修改模型属性")
     public CommonResult<String> updateModel(@RequestBody ModelUpdateVO modelUpdateVO) {
        return bpmModelService.updateModel(modelUpdateVO);
     }
 
-    @PostMapping("/deploy/{modelId}")
-    public CommonResult<String> updateModel(@PathVariable String modelId) {
+    @PostMapping("/delete")
+    @ApiOperation(value = "删除模型")
+    public CommonResult<String> deleteModel(@RequestParam String modelId) {
+       return bpmModelService.deleteModel(modelId);
+    }
+
+    @PostMapping("/deploy")
+    @ApiOperation(value = "部署模型")
+    public CommonResult<String> deploy(@RequestParam String modelId) {
        return bpmModelService.deploy(modelId);
     }
+
+    @GetMapping("/exportBpmnXml")
+    @ApiOperation(value = "导出模型")
+    public void export(@RequestParam String deploymentId, HttpServletResponse response) throws IOException {
+        FileResp fileResp = bpmModelService.exportBpmnXml(deploymentId);
+        ServletUtils.writeAttachment(response, fileResp.getFileName(), fileResp.getFileByte());
+    }
+
 }

+ 3 - 4
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/TaskController.java

@@ -60,13 +60,12 @@ public class TaskController {
         return success(bpmTaskService.getHistorySteps(processInstanceId));
     }
 
-    // TODO @Li: 项目里,暂时不使用 path 路径参数,监控等麻烦
     /**
      * 返回高亮的流转图SVG
-     * @param processInstanceId
+     * @param processInstanceId 流程Id
      */
-    @GetMapping("/process/highlight-img/{id}")
-    public void getHighlightImg(@PathVariable("id") String processInstanceId, HttpServletResponse response) throws IOException {
+    @GetMapping("/process/highlight-img")
+    public void getHighlightImg(@RequestParam String processInstanceId, HttpServletResponse response) throws IOException {
         FileResp fileResp = bpmTaskService.getHighlightImg(processInstanceId);
         ServletUtils.writeAttachment(response, fileResp.getFileName(), fileResp.getFileByte());
     }

+ 20 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelPageReqVo.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+/**
+ * @author yunlong.li
+ */
+@ApiModel("模型分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class ModelPageReqVo extends PageParam {
+    @ApiModelProperty("模型名字")
+    private String name;
+}

+ 16 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelRespVo.java

@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+/**
+ * @author yunlong.li
+ */
+@ApiModel("模型出口内容 Request VO")
+@Data
+@ToString(callSuper = true)
+public class ModelRespVo {
+}

+ 20 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/workflow/ModelConvert.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.convert.workflow;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.TodoTaskRespVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelRespVo;
+import org.activiti.api.task.model.Task;
+import org.activiti.engine.repository.Model;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+
+/**
+ * @author yunlongn
+ */
+@Mapper
+public interface ModelConvert {
+    ModelConvert INSTANCE = Mappers.getMapper(ModelConvert.class);
+
+    ModelRespVo convert(Model model);
+}

+ 1 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java

@@ -28,5 +28,6 @@ public interface BpmErrorCodeConstants {
     ErrorCode BPMN_MODEL_EDITOR_SOURCE_NOT_EXISTS = new ErrorCode(1004001001, "模型数据为空,请先成功设计流程并保存");
     ErrorCode BPMN_MODEL_ERROR = new ErrorCode(1004001002, "工作流模型异常");
     ErrorCode BPMN_MODEL_PROCESS_NOT_EXISTS = new ErrorCode(1004001003, "流程数据为空");
+    ErrorCode BPMN_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1004001004, "流程定义不存在");
 
 }

+ 37 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/BpmModelService.java

@@ -1,8 +1,15 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.service.workflow;
 
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.FileResp;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelPageReqVo;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelRespVo;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelUpdateVO;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import org.activiti.engine.repository.Model;
+
+import javax.servlet.http.HttpServletResponse;
 
 /**
  * 工作流模型接口
@@ -10,16 +17,45 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  */
 public interface BpmModelService {
 
+
+    /**
+     * 模型数据分页返回
+     * @param modelPageReqVo 分页入参
+     * @return 分页model
+     */
+    PageResult<Model> pageList(ModelPageReqVo modelPageReqVo);
+
     /**
      * 新增一个模型
      * @param modelCreateVO 模型对象
      * @return 返回成功
      */
     CommonResult<String> newModel(ModelCreateVO modelCreateVO);
-
+    /**
+     * 修改模型属性,填充bpmn数据
+     * @param modelUpdateVO 模型对象
+     * @return 返回成功
+     */
     CommonResult<String> updateModel(ModelUpdateVO modelUpdateVO);
 
+    /**
+     * 部署模型 使模型成为一个 process
+     * @param modelId 模型Id
+     * @return 返回成功
+     */
     CommonResult<String> deploy(String modelId);
 
+    /**
+     * 导出模型
+     * @param modelId 模型Id
+     * @return {@link FileResp} 返回文件
+     */
+    FileResp exportBpmnXml(String modelId);
 
+    /**
+     * 删除模型
+     * @param modelId 模型Id
+     * @return 返回成功
+     */
+    CommonResult<String> deleteModel(String modelId);
 }

+ 1 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/BpmTaskService.java

@@ -51,6 +51,7 @@ public interface BpmTaskService {
     /**
      * 返回高亮的流转进程
      * @param processInstanceId 实例Id
+     * @return {@link FileResp} 返回文件
      */
     FileResp getHighlightImg(String processInstanceId);
 }

+ 51 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/impl/BpmModelServiceImpl.java

@@ -1,28 +1,42 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.impl;
 
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.FileResp;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelPageReqVo;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelRespVo;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelUpdateVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.BpmModelService;
 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.activiti.api.runtime.shared.query.Pageable;
 import org.activiti.bpmn.converter.BpmnXMLConverter;
 import org.activiti.bpmn.model.BpmnModel;
 import org.activiti.engine.RepositoryService;
 import org.activiti.engine.repository.Deployment;
 import org.activiti.engine.repository.Model;
+import org.activiti.engine.repository.ModelQuery;
+import org.activiti.engine.repository.ProcessDefinition;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.util.ObjectUtils;
 
+import javax.servlet.http.HttpServletResponse;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamReader;
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
+import java.util.List;
 import java.util.Optional;
 
 /**
@@ -36,6 +50,19 @@ public class BpmModelServiceImpl implements BpmModelService {
 
     private final RepositoryService repositoryService;
 
+
+    @Override
+    public PageResult<Model> pageList(ModelPageReqVo modelPageReqVo) {
+        ModelQuery modelQuery = repositoryService.createModelQuery();
+        String likeName = modelPageReqVo.getName();
+        if (StrUtil.isNotBlank(likeName)){
+            modelQuery.modelNameLike("%"+likeName+"%");
+        }
+        List<Model> models = modelQuery.orderByCreateTime().desc()
+                .listPage((modelPageReqVo.getPageNo() - 1) * modelPageReqVo.getPageSize(), modelPageReqVo.getPageSize());
+        return new PageResult<>(models, modelQuery.count());
+    }
+
     @Override
     public CommonResult<String> newModel(ModelCreateVO modelCreateVO) {
         try {
@@ -119,4 +146,28 @@ public class BpmModelServiceImpl implements BpmModelService {
             throw ServiceExceptionUtil.exception(BpmErrorCodeConstants.BPMN_MODEL_ERROR);
         }
     }
+
+    @Override
+    public FileResp exportBpmnXml(String deploymentId) {
+
+        // 查询流程定义
+        ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
+        if (ObjectUtils.isEmpty(pd)) {
+            throw ServiceExceptionUtil.exception(BpmErrorCodeConstants.BPMN_PROCESS_DEFINITION_NOT_EXISTS);
+        }
+        String resourceName = Optional.ofNullable(pd.getDiagramResourceName()).orElse(pd.getResourceName());
+        InputStream inputStream = repositoryService.getResourceAsStream(deploymentId,
+                resourceName);
+        FileResp fileResp = new FileResp();
+
+        fileResp.setFileName(String.format("%s.bpmn", Optional.ofNullable(pd.getName()).orElse("流程图")));
+        fileResp.setFileByte(IoUtil.readBytes(inputStream));
+        return fileResp;
+    }
+
+    @Override
+    public CommonResult<String> deleteModel(String modelId) {
+        repositoryService.deleteModel(modelId);
+        return CommonResult.success("删除成功");
+    }
 }

+ 15 - 4
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;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.ObjectUtils;
 
 import javax.annotation.Resource;
 import java.io.IOException;
@@ -174,6 +175,18 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         if (hpi == null) {
             throw exception(PROCESS_INSTANCE_NOT_EXISTS);
         }
+        // 如果有结束时间 返回model的流程图
+        if (!ObjectUtils.isEmpty(hpi.getEndTime())) {
+            ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(hpi.getProcessDefinitionId()).singleResult();
+            String resourceName = Optional.ofNullable(pd.getDiagramResourceName()).orElse(pd.getResourceName());
+            BpmnModel bpmnModel = repositoryService.getBpmnModel(pd.getId());
+            InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, new ArrayList<>(1), new ArrayList<>(1),
+                    "宋体", "宋体", "宋体");
+            FileResp fileResp = new FileResp();
+            fileResp.setFileName( resourceName + ".svg");
+            fileResp.setFileByte(IoUtil.readBytes(inputStream));
+            return fileResp;
+        }
         // 没有结束时间。说明流程在执行过程中
         // TODO @Li:一些 runtimeService 的查询,貌似比较通用,是不是抽一些小方法出来
         ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
@@ -195,13 +208,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         try (InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, highLightedActivities, highLightedFlowIds,
                 "宋体", "宋体", "宋体")){
             FileResp fileResp = new FileResp();
-            String picName = hpi.getProcessDefinitionName() + ".svg"; // TODO @Li:一次性的变量,可以直接 set 的时候,直接拼接
-            fileResp.setFileName(picName);
+            fileResp.setFileName( hpi.getProcessDefinitionName() + ".svg");
             fileResp.setFileByte(IoUtil.readBytes(inputStream));
             return fileResp;
         } catch (IOException e) {
-            // TODO @Li:log.error("[getHighlightImg][流程({}) 生成图表失败]", processInstanceId, e)
-            log.error(ExceptionUtils.getStackTrace(e));
+            log.error("[getHighlightImg][流程({}) 生成图表失败]", processInstanceId, e);
             throw exception(HIGHLIGHT_IMG_ERROR);
         }
     }

+ 1 - 1
yudao-admin-ui/src/api/oa/todo.js

@@ -85,7 +85,7 @@ export function processHistorySteps(id) {
 
 export function getHighlightImg(id) {
   return request({
-    url: '/workflow/task/process/highlight-img/'+id,
+    url: '/workflow/task/process/highlight-img?processInstanceId='+id,
     method: 'get'
   })
 }