diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/ModelController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/ModelController.java new file mode 100644 index 00000000..fde29be4 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/ModelController.java @@ -0,0 +1,53 @@ +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.TodoTaskRespVO; +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO; +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 com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.swagger.annotations.Api; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.activiti.engine.*; +import org.activiti.engine.repository.Model; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +/** + * 工作流模型 + * @author yunlongn + */ +@Slf4j +@RestController +@RequestMapping("/workflow/models") +@Api(tags = "工作流模型") +@RequiredArgsConstructor +public class ModelController { + + private final BpmModelService bpmModelService; + + @PostMapping("/create") + public CommonResult newModel(@RequestBody ModelCreateVO modelCreateVO) { + return bpmModelService.newModel(modelCreateVO); + } + + @PostMapping("/update") + public CommonResult updateModel(@RequestBody ModelUpdateVO modelUpdateVO) { + return bpmModelService.updateModel(modelUpdateVO); + } + + @PostMapping("/deploy/{modelId}") + public CommonResult updateModel(@PathVariable String modelId) { + return bpmModelService.deploy(modelId); + } +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelCreateVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelCreateVO.java new file mode 100644 index 00000000..1600a75a --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelCreateVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 新增模型 VO + * @author yunlongn + */ +@Data +public class ModelCreateVO { + + @ApiModelProperty(value = "模型名字", required = true) + private String name; + + @ApiModelProperty(value = "模型描述") + private String description; + + @ApiModelProperty(value = "版本号") + private Integer revision; + + @ApiModelProperty(value = "key值") + private String key; +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelUpdateVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelUpdateVO.java new file mode 100644 index 00000000..59bdea82 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/model/ModelUpdateVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 新增模型 VO + * @author yunlongn + */ +@Data +public class ModelUpdateVO { + + @ApiModelProperty(value = "模型Id", required = true) + private String id; + + @ApiModelProperty(value = "模型名字", required = true) + private String name; + + @ApiModelProperty(value = "模型描述") + private String description; + + @ApiModelProperty(value = "版本号") + private Integer revision; + + @ApiModelProperty(value = "key值") + private String key; + + @ApiModelProperty(value = "bpmnXml") + private String bpmnXml; + + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java index 67e65047..e3a4ce54 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java @@ -23,4 +23,8 @@ public interface BpmErrorCodeConstants { ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1003001006, "HR岗位未设置"); ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1003001007, "请假天数必须>=1"); + + // ========== OA 工作流模块 1-004-001-000 ========== + ErrorCode BPMN_MODEL_EDITOR_SOURCE_NOT_EXISTS = new ErrorCode(1004001001, "模型数据为空,请先成功设计流程并保存"); + } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/BpmModelService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/BpmModelService.java new file mode 100644 index 00000000..ed2782a6 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/BpmModelService.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.adminserver.modules.bpm.service.workflow; + +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO; +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelUpdateVO; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; + +/** + * 工作流模型接口 + * @author yunlongn + */ +public interface BpmModelService { + + /** + * 新增一个模型 + * @param modelCreateVO 模型对象 + * @return 返回成功 + */ + CommonResult newModel(ModelCreateVO modelCreateVO); + + CommonResult updateModel(ModelUpdateVO modelUpdateVO); + + CommonResult deploy(String modelId); + + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/impl/BpmModelServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/impl/BpmModelServiceImpl.java new file mode 100644 index 00000000..bbc2480d --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/workflow/impl/BpmModelServiceImpl.java @@ -0,0 +1,112 @@ +package cn.iocoder.yudao.adminserver.modules.bpm.service.workflow.impl; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.model.ModelCreateVO; +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.adminserver.modules.tool.framework.errorcode.config.ErrorCodeProperties; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.activiti.bpmn.converter.BpmnXMLConverter; +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.engine.RepositoryService; +import org.activiti.engine.repository.Model; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.NOTICE_NOT_FOUND; + +/** + * 工作流模型实现 + * @author yunlongn + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class BpmModelServiceImpl implements BpmModelService { + + private final RepositoryService repositoryService; + + @Override + public CommonResult newModel(ModelCreateVO modelCreateVO) { + try { + //初始化一个空模型 + Model model = repositoryService.newModel(); + String name = Optional.ofNullable(modelCreateVO.getName()).orElse("new-process"); + //设置一些默认信息 + model.setName(name); + model.setKey(Optional.ofNullable(modelCreateVO.getKey()).orElse("processKey")); + model.setMetaInfo(JsonUtils.toJsonString(modelCreateVO)); + repositoryService.saveModel(model); + return CommonResult.success("success"); + }catch (Exception e){ + log.info("模型创建失败!modelCreateVO = {} e = {} ", modelCreateVO, ExceptionUtils.getStackTrace(e)); + } + + return CommonResult.success("success"); + } + + @Override + public CommonResult updateModel(ModelUpdateVO modelUpdateVO) { + try { + Model model = repositoryService.getModel(modelUpdateVO.getId()); + + // 只能修改名字跟描述 + ModelCreateVO modelCreateVO = JsonUtils.parseObject(model.getMetaInfo(), ModelCreateVO.class); + modelCreateVO.setName(modelUpdateVO.getName()); + modelCreateVO.setDescription(modelUpdateVO.getDescription()); + model.setMetaInfo(JsonUtils.toJsonString(modelCreateVO)); + model.setName(modelUpdateVO.getName()); + + repositoryService.saveModel(model); + + repositoryService.addModelEditorSource(model.getId(), modelUpdateVO.getBpmnXml().getBytes(StandardCharsets.UTF_8)); + + return CommonResult.success("success"); + }catch (Exception e){ + log.info("模型修改失败!modelCreateVO = {} e = {} ", modelUpdateVO, ExceptionUtils.getStackTrace(e)); + } + + return CommonResult.success("success"); + } + + @Override + public CommonResult deploy(String modelId) { + // 获取模型 + Model modelData = repositoryService.getModel(modelId); + byte[] bytes = repositoryService.getModelEditorSource(modelData.getId()); + if (bytes == null) { + throw ServiceExceptionUtil.exception(BpmErrorCodeConstants.BPMN_MODEL_EDITOR_SOURCE_NOT_EXISTS); + } + try { + // 将xml转换为流 + ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); + XMLInputFactory xif = XMLInputFactory.newInstance(); + InputStreamReader in = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + XMLStreamReader xtr = xif.createXMLStreamReader(in); + BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xtr); + log.info("model ={} ", model); + } catch (Exception e) { + log.error("e {}", e); + } + + return CommonResult.success("success"); + } +} diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java index fb950318..542af776 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java +++ b/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; import cn.hutool.core.util.StrUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -43,6 +44,14 @@ public class JsonUtils { } } + public static byte[] toJsonByte(Object object) { + try { + return objectMapper.writeValueAsBytes(object); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + public static T parseObject(String text, Class clazz) { if (StrUtil.isEmpty(text)) { return null; @@ -84,4 +93,20 @@ public class JsonUtils { } } + public static JsonNode readTree(String text) { + try { + return objectMapper.readTree(text); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static JsonNode readTree(byte[] text) { + try { + return objectMapper.readTree(text); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }