Commit cfdf04981a2ce2f85fa28897491c0260a8b8a1be
1 parent
89f51fe5
fix: 新增工作流模型
Showing
7 changed files
with
275 additions
and
0 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/ModelController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.TodoTaskRespVO; | ||
| 5 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO; | ||
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelUpdateVO; | ||
| 7 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.BpmModelService; | ||
| 8 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 9 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 10 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 11 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 12 | +import io.swagger.annotations.Api; | ||
| 13 | +import lombok.RequiredArgsConstructor; | ||
| 14 | +import lombok.extern.slf4j.Slf4j; | ||
| 15 | +import org.activiti.engine.*; | ||
| 16 | +import org.activiti.engine.repository.Model; | ||
| 17 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 18 | +import org.springframework.stereotype.Controller; | ||
| 19 | +import org.springframework.web.bind.annotation.*; | ||
| 20 | + | ||
| 21 | +import javax.servlet.http.HttpServletRequest; | ||
| 22 | +import javax.servlet.http.HttpServletResponse; | ||
| 23 | +import java.io.IOException; | ||
| 24 | +import java.io.UnsupportedEncodingException; | ||
| 25 | + | ||
| 26 | +/** | ||
| 27 | + * 工作流模型 | ||
| 28 | + * @author yunlongn | ||
| 29 | + */ | ||
| 30 | +@Slf4j | ||
| 31 | +@RestController | ||
| 32 | +@RequestMapping("/workflow/models") | ||
| 33 | +@Api(tags = "工作流模型") | ||
| 34 | +@RequiredArgsConstructor | ||
| 35 | +public class ModelController { | ||
| 36 | + | ||
| 37 | + private final BpmModelService bpmModelService; | ||
| 38 | + | ||
| 39 | + @PostMapping("/create") | ||
| 40 | + public CommonResult<String> newModel(@RequestBody ModelCreateVO modelCreateVO) { | ||
| 41 | + return bpmModelService.newModel(modelCreateVO); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + @PostMapping("/update") | ||
| 45 | + public CommonResult<String> updateModel(@RequestBody ModelUpdateVO modelUpdateVO) { | ||
| 46 | + return bpmModelService.updateModel(modelUpdateVO); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + @PostMapping("/deploy/{modelId}") | ||
| 50 | + public CommonResult<String> updateModel(@PathVariable String modelId) { | ||
| 51 | + return bpmModelService.deploy(modelId); | ||
| 52 | + } | ||
| 53 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelCreateVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model; | ||
| 2 | + | ||
| 3 | +import io.swagger.annotations.ApiModelProperty; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 新增模型 VO | ||
| 8 | + * @author yunlongn | ||
| 9 | + */ | ||
| 10 | +@Data | ||
| 11 | +public class ModelCreateVO { | ||
| 12 | + | ||
| 13 | + @ApiModelProperty(value = "模型名字", required = true) | ||
| 14 | + private String name; | ||
| 15 | + | ||
| 16 | + @ApiModelProperty(value = "模型描述") | ||
| 17 | + private String description; | ||
| 18 | + | ||
| 19 | + @ApiModelProperty(value = "版本号") | ||
| 20 | + private Integer revision; | ||
| 21 | + | ||
| 22 | + @ApiModelProperty(value = "key值") | ||
| 23 | + private String key; | ||
| 24 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelUpdateVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model; | ||
| 2 | + | ||
| 3 | +import io.swagger.annotations.ApiModelProperty; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 新增模型 VO | ||
| 8 | + * @author yunlongn | ||
| 9 | + */ | ||
| 10 | +@Data | ||
| 11 | +public class ModelUpdateVO { | ||
| 12 | + | ||
| 13 | + @ApiModelProperty(value = "模型Id", required = true) | ||
| 14 | + private String id; | ||
| 15 | + | ||
| 16 | + @ApiModelProperty(value = "模型名字", required = true) | ||
| 17 | + private String name; | ||
| 18 | + | ||
| 19 | + @ApiModelProperty(value = "模型描述") | ||
| 20 | + private String description; | ||
| 21 | + | ||
| 22 | + @ApiModelProperty(value = "版本号") | ||
| 23 | + private Integer revision; | ||
| 24 | + | ||
| 25 | + @ApiModelProperty(value = "key值") | ||
| 26 | + private String key; | ||
| 27 | + | ||
| 28 | + @ApiModelProperty(value = "bpmnXml") | ||
| 29 | + private String bpmnXml; | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java
| @@ -23,4 +23,8 @@ public interface BpmErrorCodeConstants { | @@ -23,4 +23,8 @@ public interface BpmErrorCodeConstants { | ||
| 23 | ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1003001006, "HR岗位未设置"); | 23 | ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1003001006, "HR岗位未设置"); |
| 24 | ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1003001007, "请假天数必须>=1"); | 24 | ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1003001007, "请假天数必须>=1"); |
| 25 | 25 | ||
| 26 | + | ||
| 27 | + // ========== OA 工作流模块 1-004-001-000 ========== | ||
| 28 | + ErrorCode BPMN_MODEL_EDITOR_SOURCE_NOT_EXISTS = new ErrorCode(1004001001, "模型数据为空,请先成功设计流程并保存"); | ||
| 29 | + | ||
| 26 | } | 30 | } |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/BpmModelService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.service.workflow; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO; | ||
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelUpdateVO; | ||
| 5 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 工作流模型接口 | ||
| 9 | + * @author yunlongn | ||
| 10 | + */ | ||
| 11 | +public interface BpmModelService { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * 新增一个模型 | ||
| 15 | + * @param modelCreateVO 模型对象 | ||
| 16 | + * @return 返回成功 | ||
| 17 | + */ | ||
| 18 | + CommonResult<String> newModel(ModelCreateVO modelCreateVO); | ||
| 19 | + | ||
| 20 | + CommonResult<String> updateModel(ModelUpdateVO modelUpdateVO); | ||
| 21 | + | ||
| 22 | + CommonResult<String> deploy(String modelId); | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/impl/BpmModelServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.impl; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 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.ModelUpdateVO; | ||
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants; | ||
| 7 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.BpmModelService; | ||
| 8 | +import cn.iocoder.yudao.adminserver.modules.tool.framework.errorcode.config.ErrorCodeProperties; | ||
| 9 | +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | ||
| 10 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 11 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||
| 12 | +import com.fasterxml.jackson.databind.JsonNode; | ||
| 13 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 14 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 15 | +import lombok.RequiredArgsConstructor; | ||
| 16 | +import lombok.extern.slf4j.Slf4j; | ||
| 17 | +import org.activiti.bpmn.converter.BpmnXMLConverter; | ||
| 18 | +import org.activiti.bpmn.model.BpmnModel; | ||
| 19 | +import org.activiti.engine.RepositoryService; | ||
| 20 | +import org.activiti.engine.repository.Model; | ||
| 21 | +import org.apache.commons.lang3.exception.ExceptionUtils; | ||
| 22 | +import org.springframework.stereotype.Service; | ||
| 23 | +import org.springframework.web.bind.annotation.PathVariable; | ||
| 24 | +import org.springframework.web.bind.annotation.ResponseBody; | ||
| 25 | + | ||
| 26 | +import javax.xml.stream.XMLInputFactory; | ||
| 27 | +import javax.xml.stream.XMLStreamReader; | ||
| 28 | +import java.io.*; | ||
| 29 | +import java.nio.charset.StandardCharsets; | ||
| 30 | +import java.util.HashMap; | ||
| 31 | +import java.util.Map; | ||
| 32 | +import java.util.Optional; | ||
| 33 | + | ||
| 34 | +import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.NOTICE_NOT_FOUND; | ||
| 35 | + | ||
| 36 | +/** | ||
| 37 | + * 工作流模型实现 | ||
| 38 | + * @author yunlongn | ||
| 39 | + */ | ||
| 40 | +@Slf4j | ||
| 41 | +@Service | ||
| 42 | +@RequiredArgsConstructor | ||
| 43 | +public class BpmModelServiceImpl implements BpmModelService { | ||
| 44 | + | ||
| 45 | + private final RepositoryService repositoryService; | ||
| 46 | + | ||
| 47 | + @Override | ||
| 48 | + public CommonResult<String> newModel(ModelCreateVO modelCreateVO) { | ||
| 49 | + try { | ||
| 50 | + //初始化一个空模型 | ||
| 51 | + Model model = repositoryService.newModel(); | ||
| 52 | + String name = Optional.ofNullable(modelCreateVO.getName()).orElse("new-process"); | ||
| 53 | + //设置一些默认信息 | ||
| 54 | + model.setName(name); | ||
| 55 | + model.setKey(Optional.ofNullable(modelCreateVO.getKey()).orElse("processKey")); | ||
| 56 | + model.setMetaInfo(JsonUtils.toJsonString(modelCreateVO)); | ||
| 57 | + repositoryService.saveModel(model); | ||
| 58 | + return CommonResult.success("success"); | ||
| 59 | + }catch (Exception e){ | ||
| 60 | + log.info("模型创建失败!modelCreateVO = {} e = {} ", modelCreateVO, ExceptionUtils.getStackTrace(e)); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + return CommonResult.success("success"); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + @Override | ||
| 67 | + public CommonResult<String> updateModel(ModelUpdateVO modelUpdateVO) { | ||
| 68 | + try { | ||
| 69 | + Model model = repositoryService.getModel(modelUpdateVO.getId()); | ||
| 70 | + | ||
| 71 | + // 只能修改名字跟描述 | ||
| 72 | + ModelCreateVO modelCreateVO = JsonUtils.parseObject(model.getMetaInfo(), ModelCreateVO.class); | ||
| 73 | + modelCreateVO.setName(modelUpdateVO.getName()); | ||
| 74 | + modelCreateVO.setDescription(modelUpdateVO.getDescription()); | ||
| 75 | + model.setMetaInfo(JsonUtils.toJsonString(modelCreateVO)); | ||
| 76 | + model.setName(modelUpdateVO.getName()); | ||
| 77 | + | ||
| 78 | + repositoryService.saveModel(model); | ||
| 79 | + | ||
| 80 | + repositoryService.addModelEditorSource(model.getId(), modelUpdateVO.getBpmnXml().getBytes(StandardCharsets.UTF_8)); | ||
| 81 | + | ||
| 82 | + return CommonResult.success("success"); | ||
| 83 | + }catch (Exception e){ | ||
| 84 | + log.info("模型修改失败!modelCreateVO = {} e = {} ", modelUpdateVO, ExceptionUtils.getStackTrace(e)); | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + return CommonResult.success("success"); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + @Override | ||
| 91 | + public CommonResult<String> deploy(String modelId) { | ||
| 92 | + // 获取模型 | ||
| 93 | + Model modelData = repositoryService.getModel(modelId); | ||
| 94 | + byte[] bytes = repositoryService.getModelEditorSource(modelData.getId()); | ||
| 95 | + if (bytes == null) { | ||
| 96 | + throw ServiceExceptionUtil.exception(BpmErrorCodeConstants.BPMN_MODEL_EDITOR_SOURCE_NOT_EXISTS); | ||
| 97 | + } | ||
| 98 | + try { | ||
| 99 | + // 将xml转换为流 | ||
| 100 | + ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); | ||
| 101 | + XMLInputFactory xif = XMLInputFactory.newInstance(); | ||
| 102 | + InputStreamReader in = new InputStreamReader(inputStream, StandardCharsets.UTF_8); | ||
| 103 | + XMLStreamReader xtr = xif.createXMLStreamReader(in); | ||
| 104 | + BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xtr); | ||
| 105 | + log.info("model ={} ", model); | ||
| 106 | + } catch (Exception e) { | ||
| 107 | + log.error("e {}", e); | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + return CommonResult.success("success"); | ||
| 111 | + } | ||
| 112 | +} |
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java
| @@ -4,6 +4,7 @@ import cn.hutool.core.util.ArrayUtil; | @@ -4,6 +4,7 @@ import cn.hutool.core.util.ArrayUtil; | ||
| 4 | import cn.hutool.core.util.StrUtil; | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | import com.fasterxml.jackson.core.JsonProcessingException; | 5 | import com.fasterxml.jackson.core.JsonProcessingException; |
| 6 | import com.fasterxml.jackson.core.type.TypeReference; | 6 | import com.fasterxml.jackson.core.type.TypeReference; |
| 7 | +import com.fasterxml.jackson.databind.JsonNode; | ||
| 7 | import com.fasterxml.jackson.databind.ObjectMapper; | 8 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 8 | import com.fasterxml.jackson.databind.SerializationFeature; | 9 | import com.fasterxml.jackson.databind.SerializationFeature; |
| 9 | 10 | ||
| @@ -43,6 +44,14 @@ public class JsonUtils { | @@ -43,6 +44,14 @@ public class JsonUtils { | ||
| 43 | } | 44 | } |
| 44 | } | 45 | } |
| 45 | 46 | ||
| 47 | + public static byte[] toJsonByte(Object object) { | ||
| 48 | + try { | ||
| 49 | + return objectMapper.writeValueAsBytes(object); | ||
| 50 | + } catch (JsonProcessingException e) { | ||
| 51 | + throw new RuntimeException(e); | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | + | ||
| 46 | public static <T> T parseObject(String text, Class<T> clazz) { | 55 | public static <T> T parseObject(String text, Class<T> clazz) { |
| 47 | if (StrUtil.isEmpty(text)) { | 56 | if (StrUtil.isEmpty(text)) { |
| 48 | return null; | 57 | return null; |
| @@ -84,4 +93,20 @@ public class JsonUtils { | @@ -84,4 +93,20 @@ public class JsonUtils { | ||
| 84 | } | 93 | } |
| 85 | } | 94 | } |
| 86 | 95 | ||
| 96 | + public static JsonNode readTree(String text) { | ||
| 97 | + try { | ||
| 98 | + return objectMapper.readTree(text); | ||
| 99 | + } catch (IOException e) { | ||
| 100 | + throw new RuntimeException(e); | ||
| 101 | + } | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + public static JsonNode readTree(byte[] text) { | ||
| 105 | + try { | ||
| 106 | + return objectMapper.readTree(text); | ||
| 107 | + } catch (IOException e) { | ||
| 108 | + throw new RuntimeException(e); | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + | ||
| 87 | } | 112 | } |