Bläddra i källkod

!61 工作流的动态表单、流程模型、流程定义的提交
Merge pull request !61 from 芋道源码/feature/activiti

芋道源码 3 år sedan
förälder
incheckning
2a90038080
100 ändrade filer med 2374 tillägg och 1385 borttagningar
  1. 24 1
      sql/ruoyi-vue-pro.sql
  2. 0 100
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/WlFormController.java
  3. 0 28
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormBaseVO.java
  4. 0 12
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormCreateReqVO.java
  5. 0 34
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormExcelVO.java
  6. 0 33
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormExportReqVO.java
  7. 0 36
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormPageReqVO.java
  8. 0 19
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormRespVO.java
  9. 0 17
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormUpdateReqVO.java
  10. 0 15
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveCreateReqVO.java
  11. 0 34
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/ProcessDefinitionController.java
  12. 0 36
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/form/WfFormConvert.java
  13. 0 34
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/oa/OaLeaveConvert.java
  14. 0 9
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/workflow/TodoTaskConvert.java
  15. 0 29
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/dataobject/process/ProcessDefinitionDO.java
  16. 0 43
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/mysql/form/WfFormMapper.java
  17. 0 13
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/enums/OaErrorCodeConstants.java
  18. 0 14
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/enums/form/WfFormErrorCodeConstants.java
  19. 0 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/package-info.java
  20. 0 75
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/form/WfFormService.java
  21. 0 86
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/form/impl/WfFormServiceImpl.java
  22. 0 43
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/ReportBackEndProcessor.java
  23. 0 141
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/impl/OaLeaveServiceImpl.java
  24. 0 29
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/process/ProcessService.java
  25. 0 109
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/process/impl/ProcessServiceImpl.java
  26. 0 26
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/TaskService.java
  27. 0 266
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/impl/TaskServiceImpl.java
  28. 58 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/BpmProcessDefinitionController.java
  29. 24 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/BpmProcessDefinitionPageItemRespVO.java
  30. 19 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/BpmProcessDefinitionPageReqVO.java
  31. 36 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/BpmProcessDefinitionRespVO.java
  32. 79 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/BpmFormController.java
  33. 25 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormBaseVO.java
  34. 23 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormCreateReqVO.java
  35. 19 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormPageReqVO.java
  36. 32 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormRespVO.java
  37. 17 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormSimpleRespVO.java
  38. 26 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormUpdateReqVO.java
  39. 97 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/BpmModelController.java
  40. 22 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModeImportReqVO.java
  41. 33 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelBaseVO.java
  42. 21 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelCreateReqVO.java
  43. 49 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelPageItemRespVO.java
  44. 26 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelRespVO.java
  45. 25 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelUpdateReqVO.java
  46. 21 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelUpdateStateReqVO.java
  47. 26 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/ModelPageReqVO.java
  48. 32 34
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/OALeaveController.java
  49. 25 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveApplyMembersVO.java
  50. 2 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveBaseVO.java
  51. 23 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveCreateReqVO.java
  52. 2 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveExcelVO.java
  53. 2 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveExportReqVO.java
  54. 2 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeavePageReqVO.java
  55. 2 3
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveRespVO.java
  56. 2 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveUpdateReqVO.java
  57. 13 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.http
  58. 35 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.java
  59. 23 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceCreateReqVO.java
  60. 6 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceMyPageReqVO.java
  61. 23 10
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/TaskController.java
  62. 24 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/FileResp.java
  63. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskHandleVO.java
  64. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskQueryReqVO.java
  65. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskReqVO.java
  66. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskStepVO.java
  67. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TodoTaskPageReqVO.java
  68. 6 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TodoTaskRespVO.java
  69. 58 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmDefinitionConvert.java
  70. 34 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/form/BpmFormConvert.java
  71. 118 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/model/BpmModelConvert.java
  72. 37 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/oa/OALeaveConvert.java
  73. 6 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/package-info.java
  74. 44 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/workflow/TaskConvert.java
  75. 1 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md
  76. 47 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/definition/BpmProcessDefinitionDO.java
  77. 7 7
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmFormDO.java
  78. 5 5
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmFormDataDO.java
  79. 2 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/leave/OALeaveDO.java
  80. 4 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/leave/package-info.java
  81. 4 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/package-info.java
  82. 18 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/definition/BpmProcessDefinitionMapper.java
  83. 25 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/form/BpmFormMapper.java
  84. 9 8
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/oa/OALeaveMapper.java
  85. 43 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java
  86. 29 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/FlowStatusEnum.java
  87. 9 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/package-info.java
  88. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/config/UserGroupManagerService.java
  89. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/config/UserGroupsProvider.java
  90. 115 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmProcessDefinitionService.java
  91. 43 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmDefinitionCreateReqDTO.java
  92. 193 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java
  93. 92 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/BpmFormService.java
  94. 25 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/dto/BpmFormFieldRespDTO.java
  95. 113 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/impl/BpmFormServiceImpl.java
  96. 68 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/model/BpmModelService.java
  97. 23 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/model/dto/BpmModelMetaInfoRespDTO.java
  98. 214 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/model/impl/BpmModelServiceImpl.java
  99. 40 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/LeaveApplyEndProcessor.java
  100. 17 13
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/OALeaveService.java

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 24 - 1
sql/ruoyi-vue-pro.sql


+ 0 - 100
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/WlFormController.java

@@ -1,100 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.form;
-
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.*;
-import cn.iocoder.yudao.adminserver.modules.activiti.convert.form.WfFormConvert;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
-import cn.iocoder.yudao.adminserver.modules.activiti.service.form.WfFormService;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
-
-// TODO @风里雾里: Os=》Wf,/os 改成 /wl 开头。目前这个模块,咱先定位成给工作流用的
-@Api(tags = "动态表单")
-@RestController
-@RequestMapping("/wl/form")
-@Validated
-public class WlFormController {
-
-    @Resource
-    private WfFormService formService;
-
-    @PostMapping("/create")
-    @ApiOperation("创建动态表单")
-    @PreAuthorize("@ss.hasPermission('os:form:create')")
-    public CommonResult<Long> createForm(@Valid @RequestBody WfFormCreateReqVO createReqVO) {
-        return success(formService.createForm(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @ApiOperation("更新动态表单")
-    @PreAuthorize("@ss.hasPermission('os:form:update')")
-    public CommonResult<Boolean> updateForm(@Valid @RequestBody WfFormUpdateReqVO updateReqVO) {
-        formService.updateForm(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @ApiOperation("删除动态表单")
-    @ApiImplicitParam(name = "id", value = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('os:form:delete')")
-    public CommonResult<Boolean> deleteForm(@RequestParam("id") Long id) {
-        formService.deleteForm(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @ApiOperation("获得动态表单")
-    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
-    @PreAuthorize("@ss.hasPermission('os:form:query')")
-    public CommonResult<WfFormRespVO> getForm(@RequestParam("id") Long id) {
-        WfForm form = formService.getForm(id);
-        return success(WfFormConvert.INSTANCE.convert(form));
-    }
-
-    @GetMapping("/list")
-    @ApiOperation("获得动态表单列表")
-    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
-    @PreAuthorize("@ss.hasPermission('os:form:query')")
-    public CommonResult<List<WfFormRespVO>> getFormList(@RequestParam("ids") Collection<Long> ids) {
-        List<WfForm> list = formService.getFormList(ids);
-        return success(WfFormConvert.INSTANCE.convertList(list));
-    }
-
-    @GetMapping("/page")
-    @ApiOperation("获得动态表单分页")
-    @PreAuthorize("@ss.hasPermission('os:form:query')")
-    public CommonResult<PageResult<WfFormRespVO>> getFormPage(@Valid WfFormPageReqVO pageVO) {
-        PageResult<WfForm> pageResult = formService.getFormPage(pageVO);
-        return success(WfFormConvert.INSTANCE.convertPage(pageResult));
-    }
-
-    @GetMapping("/export-excel")
-    @ApiOperation("导出动态表单 Excel")
-    @PreAuthorize("@ss.hasPermission('os:form:export')")
-    @OperateLog(type = EXPORT)
-    public void exportFormExcel(@Valid WfFormExportReqVO exportReqVO,
-              HttpServletResponse response) throws IOException {
-        List<WfForm> list = formService.getFormList(exportReqVO);
-        // 导出 Excel
-        List<WfFormExcelVO> datas = WfFormConvert.INSTANCE.convertList02(list);
-        ExcelUtils.write(response, "动态表单.xls", "数据", WfFormExcelVO.class, datas);
-    }
-
-}

+ 0 - 28
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormBaseVO.java

@@ -1,28 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
-
-import lombok.*;
-import io.swagger.annotations.*;
-import javax.validation.constraints.*;
-
-/**
-* 动态表单 Base VO,提供给添加、修改、详细的子 VO 使用
-* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
-*/
-@Data
-public class WfFormBaseVO {
-
-    @ApiModelProperty(value = "表单名称", required = true)
-    @NotNull(message = "表单名称不能为空")
-    private String name;
-
-    @ApiModelProperty(value = "商户状态", required = true)
-    @NotNull(message = "商户状态不能为空")
-    private Integer status;
-
-    @ApiModelProperty(value = "表单JSON")
-    private String formJson;
-
-    @ApiModelProperty(value = "备注")
-    private String remark;
-
-}

+ 0 - 12
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormCreateReqVO.java

@@ -1,12 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
-
-import lombok.*;
-import io.swagger.annotations.*;
-
-@ApiModel("动态表单创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class WfFormCreateReqVO extends WfFormBaseVO {
-
-}

+ 0 - 34
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormExcelVO.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
-
-import lombok.*;
-import java.util.*;
-
-import com.alibaba.excel.annotation.ExcelProperty;
-
-/**
- * 动态表单 Excel VO
- *
- * @author 芋艿
- */
-@Data
-public class WfFormExcelVO {
-
-    @ExcelProperty("表单编号")
-    private Long id;
-
-    @ExcelProperty("表单名称")
-    private String name;
-
-    @ExcelProperty("商户状态")
-    private Integer status;
-
-    @ExcelProperty("表单JSON")
-    private String formJson;
-
-    @ExcelProperty("备注")
-    private String remark;
-
-    @ExcelProperty("创建时间")
-    private Date createTime;
-
-}

+ 0 - 33
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormExportReqVO.java

@@ -1,33 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
-
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
-import org.springframework.format.annotation.DateTimeFormat;
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-@ApiModel(value = "动态表单 Excel 导出 Request VO", description = "参数和 OsFormPageReqVO 是一致的")
-@Data
-public class WfFormExportReqVO {
-
-    @ApiModelProperty(value = "表单名称")
-    private String name;
-
-    @ApiModelProperty(value = "商户状态")
-    private Integer status;
-
-    @ApiModelProperty(value = "表单JSON")
-    private String formJson;
-
-    @ApiModelProperty(value = "备注")
-    private String remark;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @ApiModelProperty(value = "开始创建时间")
-    private Date beginCreateTime;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @ApiModelProperty(value = "结束创建时间")
-    private Date endCreateTime;
-
-}

+ 0 - 36
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormPageReqVO.java

@@ -1,36 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
-
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import org.springframework.format.annotation.DateTimeFormat;
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-@ApiModel("动态表单分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class WfFormPageReqVO extends PageParam {
-
-    @ApiModelProperty(value = "表单名称")
-    private String name;
-
-    @ApiModelProperty(value = "商户状态")
-    private Integer status;
-
-    @ApiModelProperty(value = "表单JSON")
-    private String formJson;
-
-    @ApiModelProperty(value = "备注")
-    private String remark;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @ApiModelProperty(value = "开始创建时间")
-    private Date beginCreateTime;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @ApiModelProperty(value = "结束创建时间")
-    private Date endCreateTime;
-
-}

+ 0 - 19
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormRespVO.java

@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
-
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
-
-@ApiModel("动态表单 Response VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class WfFormRespVO extends WfFormBaseVO {
-
-    @ApiModelProperty(value = "表单编号", required = true)
-    private Long id;
-
-    @ApiModelProperty(value = "创建时间", required = true)
-    private Date createTime;
-
-}

+ 0 - 17
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/form/vo/WfFormUpdateReqVO.java

@@ -1,17 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo;
-
-import lombok.*;
-import io.swagger.annotations.*;
-import javax.validation.constraints.*;
-
-@ApiModel("动态表单更新 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class WfFormUpdateReqVO extends WfFormBaseVO {
-
-    @ApiModelProperty(value = "表单编号", required = true)
-    @NotNull(message = "表单编号不能为空")
-    private Long id;
-
-}

+ 0 - 15
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveCreateReqVO.java

@@ -1,15 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
-
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
-import javax.validation.constraints.*;
-
-@ApiModel("请假申请创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class OaLeaveCreateReqVO extends OaLeaveBaseVO {
-
-    private String processKey;
-}

+ 0 - 34
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/ProcessDefinitionController.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow;
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import org.activiti.api.process.runtime.ProcessRuntime;
-import org.activiti.engine.RepositoryService;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-
-// TODO @json:swagger 和 validation 的注解,后续要补全下哈。可以等 workflow 基本写的差不多之后
-@RestController
-@RequestMapping("/workflow/process/definition")
-public class ProcessDefinitionController {
-
-    @Resource
-    private RepositoryService repositoryService;
-
-    @Resource
-    private ProcessRuntime processRuntime;
-
-
-    @GetMapping(value = "/getStartForm")
-    public CommonResult<String> getStartForm(@RequestParam("processKey") String processKey){
-        //这样查似乎有问题??, 暂时写死
-//        final ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
-//                processDefinitionKey(processKey).latestVersion().singleResult();
-//        processRuntime.processDefinition(processDefinition.getId()).getFormKey();
-        return CommonResult.success("/flow/leave/apply");
-    }
-
-}

+ 0 - 36
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/form/WfFormConvert.java

@@ -1,36 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.convert.form;
-
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormCreateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormExcelVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormRespVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormUpdateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-import java.util.List;
-
-/**
- * 动态表单 Convert
- *
- * @author 芋艿
- */
-@Mapper
-public interface WfFormConvert {
-
-    WfFormConvert INSTANCE = Mappers.getMapper(WfFormConvert.class);
-
-    WfForm convert(WfFormCreateReqVO bean);
-
-    WfForm convert(WfFormUpdateReqVO bean);
-
-    WfFormRespVO convert(WfForm bean);
-
-    List<WfFormRespVO> convertList(List<WfForm> list);
-
-    PageResult<WfFormRespVO> convertPage(PageResult<WfForm> page);
-
-    List<WfFormExcelVO> convertList02(List<WfForm> list);
-
-}

+ 0 - 34
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/oa/OaLeaveConvert.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.convert.oa;
-
-import java.util.*;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
-
-/**
- * 请假申请 Convert
- *
- * @author 芋艿
- */
-@Mapper
-public interface OaLeaveConvert {
-
-    OaLeaveConvert INSTANCE = Mappers.getMapper(OaLeaveConvert.class);
-
-    OaLeaveDO convert(OaLeaveCreateReqVO bean);
-
-    OaLeaveDO convert(OaLeaveUpdateReqVO bean);
-
-    OaLeaveRespVO convert(OaLeaveDO bean);
-
-    List<OaLeaveRespVO> convertList(List<OaLeaveDO> list);
-
-    PageResult<OaLeaveRespVO> convertPage(PageResult<OaLeaveDO> page);
-
-    List<OaLeaveExcelVO> convertList02(List<OaLeaveDO> list);
-
-}

+ 0 - 9
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/workflow/TodoTaskConvert.java

@@ -1,9 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.convert.workflow;
-
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-@Mapper
-public interface TodoTaskConvert {
-    TodoTaskConvert INSTANCE = Mappers.getMapper(TodoTaskConvert.class);
-}

+ 0 - 29
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/dataobject/process/ProcessDefinitionDO.java

@@ -1,29 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.process;
-
-/**
- * 流程模型实体类 映射  activiti ProcessDefinition接口
- *
- * @author ZJQ
- * @date 2021/9/7 23:23
- */
-public class ProcessDefinitionDO {
-
-    private String id;
-
-    private String category;
-
-    private String key;
-
-    private String name;
-
-    private String version;
-
-    private String resourceName;
-
-    private String deploymentId;
-
-    private String diagramResourceName;
-
-    private boolean suspended;
-
-}

+ 0 - 43
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/mysql/form/WfFormMapper.java

@@ -1,43 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.form;
-
-
-
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormExportReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormPageReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-/**
- * 动态表单 Mapper
- *
- * @author 风里雾里
- */
-@Mapper
-public interface WfFormMapper extends BaseMapperX<WfForm> {
-
-    default PageResult<WfForm> selectPage(WfFormPageReqVO reqVO) {
-        return selectPage(reqVO, new QueryWrapperX<WfForm>()
-                .likeIfPresent("name", reqVO.getName())
-                .eqIfPresent("status", reqVO.getStatus())
-                .eqIfPresent("form_json", reqVO.getFormJson())
-                .eqIfPresent("remark", reqVO.getRemark())
-                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
-                .orderByDesc("id")        );
-    }
-
-    default List<WfForm> selectList(WfFormExportReqVO reqVO) {
-        return selectList(new QueryWrapperX<WfForm>()
-                .likeIfPresent("name", reqVO.getName())
-                .eqIfPresent("status", reqVO.getStatus())
-                .eqIfPresent("form_json", reqVO.getFormJson())
-                .eqIfPresent("remark", reqVO.getRemark())
-                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
-                .orderByDesc("id")        );
-    }
-
-}

+ 0 - 13
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/enums/OaErrorCodeConstants.java

@@ -1,13 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.enums;
-
-import cn.iocoder.yudao.framework.common.exception.ErrorCode;
-/**
- * activiti 系统 错误码枚举类
- *
- * 003 activiti
- * 001 oa
- * activiti 系统,使用 1-003-000-000 段
- */
-public interface OaErrorCodeConstants {
-    ErrorCode LEAVE_NOT_EXISTS = new ErrorCode(1003001001, "请假申请不存在");
-}

+ 0 - 14
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/enums/form/WfFormErrorCodeConstants.java

@@ -1,14 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.enums.form;
-
-import cn.iocoder.yudao.framework.common.exception.ErrorCode;
-
-/**
- * activiti 系统 错误码枚举类
- *
- * 003 activiti
- * 001 oa
- * activiti 系统,使用 1-003-000-000 段
- */
-public interface WfFormErrorCodeConstants {
-    ErrorCode FORM_NOT_EXISTS = new ErrorCode(1003001002, "动态表单不存在");
-}

+ 0 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/package-info.java

@@ -1,2 +0,0 @@
-// TODO @芋艿:思考下 activiti、oa 的定位,边界,模块的拆分
-package cn.iocoder.yudao.adminserver.modules.activiti;

+ 0 - 75
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/form/WfFormService.java

@@ -1,75 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.form;
-
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormCreateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormExportReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormPageReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormUpdateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import java.util.*;
-import javax.validation.*;
-
-
-/**
- * 动态表单 Service 接口
- *
- * TODO @风里雾里
- */
-public interface WfFormService {
-
-    /**
-     * 创建动态表单
-     *
-     * @param createReqVO 创建信息
-     * @return 编号
-     */
-    Long createForm(@Valid WfFormCreateReqVO createReqVO);
-
-    /**
-     * 更新动态表单
-     *
-     * @param updateReqVO 更新信息
-     */
-    void updateForm(@Valid WfFormUpdateReqVO updateReqVO);
-
-    /**
-     * 删除动态表单
-     *
-     * @param id 编号
-     */
-    void deleteForm(Long id);
-
-    /**
-     * 获得动态表单
-     *
-     * @param id 编号
-     * @return 动态表单
-     */
-    WfForm getForm(Long id);
-
-    /**
-     * 获得动态表单列表
-     *
-     * @param ids 编号
-     * @return 动态表单列表
-     */
-    List<WfForm> getFormList(Collection<Long> ids);
-
-    /**
-     * 获得动态表单分页
-     *
-     * @param pageReqVO 分页查询
-     * @return 动态表单分页
-     */
-    PageResult<WfForm> getFormPage(WfFormPageReqVO pageReqVO);
-
-    /**
-     * 获得动态表单列表, 用于 Excel 导出
-     *
-     * @param exportReqVO 查询条件
-     * @return 动态表单列表
-     */
-    List<WfForm> getFormList(WfFormExportReqVO exportReqVO);
-
-}

+ 0 - 86
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/form/impl/WfFormServiceImpl.java

@@ -1,86 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.form.impl;
-
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormCreateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormExportReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormPageReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.form.vo.WfFormUpdateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.convert.form.WfFormConvert;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form.WfForm;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.form.WfFormMapper;
-import cn.iocoder.yudao.adminserver.modules.activiti.service.form.WfFormService;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import org.springframework.stereotype.Service;
-import org.springframework.validation.annotation.Validated;
-
-import javax.annotation.Resource;
-import java.util.Collection;
-import java.util.List;
-
-import static cn.iocoder.yudao.adminserver.modules.activiti.enums.form.WfFormErrorCodeConstants.FORM_NOT_EXISTS;
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-
-/**
- * 动态表单 Service 实现类
- *
- * TODO @风里雾里
- */
-@Service
-@Validated
-public class WfFormServiceImpl implements WfFormService {
-
-    @Resource
-    private WfFormMapper formMapper;
-
-    @Override
-    public Long createForm(WfFormCreateReqVO createReqVO) {
-        // 插入
-        WfForm form = WfFormConvert.INSTANCE.convert(createReqVO);
-        formMapper.insert(form);
-        // 返回
-        return form.getId();
-    }
-
-    @Override
-    public void updateForm(WfFormUpdateReqVO updateReqVO) {
-        // 校验存在
-        this.validateFormExists(updateReqVO.getId());
-        // 更新
-        WfForm updateObj = WfFormConvert.INSTANCE.convert(updateReqVO);
-        formMapper.updateById(updateObj);
-    }
-
-    @Override
-    public void deleteForm(Long id) {
-        // 校验存在
-        this.validateFormExists(id);
-        // 删除
-        formMapper.deleteById(id);
-    }
-
-    private void validateFormExists(Long id) {
-        if (formMapper.selectById(id) == null) {
-            throw exception(FORM_NOT_EXISTS);
-        }
-    }
-
-    @Override
-    public WfForm getForm(Long id) {
-        return formMapper.selectById(id);
-    }
-
-    @Override
-    public List<WfForm> getFormList(Collection<Long> ids) {
-        return formMapper.selectBatchIds(ids);
-    }
-
-    @Override
-    public PageResult<WfForm> getFormPage(WfFormPageReqVO pageReqVO) {
-        return formMapper.selectPage(pageReqVO);
-    }
-
-    @Override
-    public List<WfForm> getFormList(WfFormExportReqVO exportReqVO) {
-        return formMapper.selectList(exportReqVO);
-    }
-
-}

+ 0 - 43
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/ReportBackEndProcessor.java

@@ -1,43 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.oa;
-
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
-import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.ExecutionListener;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.Resource;
-
-@Component
-public class ReportBackEndProcessor implements ExecutionListener {
-
-    @Resource
-    private OaLeaveMapper leaveMapper;
-
-
-//    @Override
-//    @Transactional(rollbackFor = Exception.class)
-//    public void notify(DelegateTask delegateTask) {
-//        final String businessKey = delegateTask.getExecution().getProcessInstanceBusinessKey();
-//        UpdateWrapper<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
-//        updateWrapper.eq("id", Long.valueOf(businessKey));
-//        OaLeaveDO updateDo = new OaLeaveDO();
-//        updateDo.setStatus(2);
-//        leaveMapper.update(updateDo, updateWrapper);
-//    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void notify(DelegateExecution delegateExecution) {
-        final String businessKey = delegateExecution.getProcessInstanceBusinessKey();
-        // TODO @json:service 不要出现 dao 的元素,例如说 UpdateWrapper。这里,我们可以调用 updateById 方法
-        UpdateWrapper<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.eq("id", Long.valueOf(businessKey));
-        OaLeaveDO updateDo = new OaLeaveDO();
-        updateDo.setStatus(2);  // TODO @json:status 要枚举起来,不要出现 magic number
-        leaveMapper.update(updateDo, updateWrapper);
-    }
-
-}

+ 0 - 141
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/impl/OaLeaveServiceImpl.java

@@ -1,141 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.oa.impl;
-
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveCreateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveExportReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeavePageReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveUpdateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.convert.oa.OaLeaveConvert;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
-import cn.iocoder.yudao.adminserver.modules.activiti.service.oa.OaLeaveService;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
-import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
-import org.activiti.api.task.model.Task;
-import org.activiti.api.task.model.builders.TaskPayloadBuilder;
-import org.activiti.api.task.runtime.TaskRuntime;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.validation.annotation.Validated;
-
-import javax.annotation.Resource;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static cn.iocoder.yudao.adminserver.modules.activiti.enums.OaErrorCodeConstants.LEAVE_NOT_EXISTS;
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-
-/**
- * 请假申请 Service 实现类
- *
- * @author 芋艿
- */
-@Service
-@Validated
-public class OaLeaveServiceImpl implements OaLeaveService {
-
-    @Resource
-    private OaLeaveMapper leaveMapper;
-
-    @Resource
-    private RuntimeService runtimeService;
-
-    @Resource
-    private org.activiti.engine.TaskService activitiTaskService;
-
-    @Resource
-    private TaskRuntime taskRuntime;
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Long createLeave(OaLeaveCreateReqVO createReqVO) {
-        // 插入 OA 请假单
-        OaLeaveDO leave = OaLeaveConvert.INSTANCE.convert(createReqVO);
-        leave.setStatus(1);
-        leave.setUserId(SecurityFrameworkUtils.getLoginUser().getUsername());
-        leaveMapper.insert(leave);
-
-        // 创建工作流
-        Map<String, Object> variables = new HashMap<>();
-        // 如何得到部门领导人,暂时写死
-        variables.put("deptLeader", "admin"); // TODO @芋艿:需要部门的负责人
-        Long id = leave.getId();
-        String businessKey = String.valueOf(id);
-        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(createReqVO.getProcessKey(), businessKey, variables);
-        String processInstanceId = processInstance.getProcessInstanceId();
-
-        // TODO @json:service 不要出现 dao 的元素,例如说 UpdateWrapper。这里,我们可以调用 updateById 方法
-        // 将工作流的编号,更新到 OA 请假单中
-        UpdateWrapper<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.eq("id", id);
-        OaLeaveDO updateDo = new OaLeaveDO();
-        updateDo.setProcessInstanceId(processInstanceId);
-        leaveMapper.update(updateDo, updateWrapper);
-        return id;
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void updateLeave(OaLeaveUpdateReqVO updateReqVO) {
-        // 校验存在
-        this.validateLeaveExists(updateReqVO.getId());
-
-        final Task task = taskRuntime.task(updateReqVO.getTaskId());
-        activitiTaskService.addComment(task.getId(), task.getProcessInstanceId(), updateReqVO.getComment());
-        Map<String, Object> variables = updateReqVO.getVariables();
-
-        //如何得到部门领导人, 暂时写死
-        variables.put("deptLeader", "admin");
-        taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId())
-                .withVariables(variables)
-                .build());
-        // TODO @jason:不需要加 final 哈。虽然是不变,但是代码比较少这么去写
-        final Object reApply = variables.get("reApply");
-        // TODO @jason:直接使用 Objects.equals(reApply, true) 就可以
-        if((reApply instanceof Boolean) && (Boolean)reApply){
-            // 更新 表单
-            OaLeaveDO updateObj = OaLeaveConvert.INSTANCE.convert(updateReqVO);
-            leaveMapper.updateById(updateObj);
-        }
-    }
-
-    @Override
-    public void deleteLeave(Long id) {
-        // 校验存在
-        this.validateLeaveExists(id);
-        // 删除
-        leaveMapper.deleteById(id);
-        // TODO @jason:需要调用 runtimeService 的 delete 方法,删除???
-    }
-
-    private void validateLeaveExists(Long id) {
-        if (leaveMapper.selectById(id) == null) {
-            throw exception(LEAVE_NOT_EXISTS);
-        }
-    }
-
-    @Override
-    public OaLeaveDO getLeave(Long id) {
-        return leaveMapper.selectById(id);
-    }
-
-    @Override
-    public List<OaLeaveDO> getLeaveList(Collection<Long> ids) {
-        return leaveMapper.selectBatchIds(ids);
-    }
-
-    @Override
-    public PageResult<OaLeaveDO> getLeavePage(OaLeavePageReqVO pageReqVO) {
-        return leaveMapper.selectPage(pageReqVO);
-    }
-
-    @Override
-    public List<OaLeaveDO> getLeaveList(OaLeaveExportReqVO exportReqVO) {
-        return leaveMapper.selectList(exportReqVO);
-    }
-
-}

+ 0 - 29
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/process/ProcessService.java

@@ -1,29 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.process;
-
-import org.springframework.web.multipart.MultipartFile;
-
-/**
- * 流程基础管理
- *
- * @author ZJQ
- * @date 2021/9/5 21:00
- */
-public interface ProcessService {
-
-    /**
-     * 上传流程文件,进行流程模型部署
-     * @param multipartFile 上传文件
-     */
-    void deployProcess(MultipartFile multipartFile);
-
-
-    /**
-     * 激活或者挂起流程模型实体
-     * @param processDefinitionId 流程模型实体id
-     * @param type 类型
-     * @return 状态
-     */
-    String setActivOrHang(String processDefinitionId,String type);
-
-
-}

+ 0 - 109
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/process/impl/ProcessServiceImpl.java

@@ -1,109 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.process.impl;
-
-import cn.iocoder.yudao.adminserver.modules.activiti.service.process.ProcessService;
-import lombok.extern.slf4j.Slf4j;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.repository.Deployment;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.apache.commons.io.FilenameUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.annotation.Resource;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.zip.ZipInputStream;
-import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.FILE_UPLOAD_FAILED;
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-
-/**
- * 流程基础管理
- *
- * @author ZJQ
- * @date 2021/9/5 21:04
- */
-@Service
-@Slf4j
-public class ProcessServiceImpl implements ProcessService {
-
-    private static final String BPMN20_XML = "bpmn20.xml";
-
-    @Resource
-    private RepositoryService repositoryService;
-
-    /**
-     * 上传流程文件,进行流程部署
-     * @param multipartFile 上传文件
-     */
-    @Override
-    public void deployProcess(MultipartFile multipartFile) {
-        String fileName = multipartFile.getOriginalFilename();
-        try (InputStream inputStream = multipartFile.getInputStream()){
-            Deployment deployment = getDeplymentByType(inputStream,fileName);
-            //获取部署成功的流程模型
-            List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list();
-            processDefinitions.forEach((processDefinition)->{
-                //设置线上部署流程模型名字
-                String proDefId = processDefinition.getId();
-                repositoryService.setProcessDefinitionCategory(proDefId,fileName);
-                log.info("流程文件部署成功,流程ID="+proDefId);
-            });
-        } catch (IOException e) {
-           log.error("流程部署出现异常"+e);
-        }
-    }
-
-    /**
-     * 激活或者挂起流程模型实体
-     * @param processDefinitionId 流程模型实体id
-     * @param type 类型
-     * @return 提示
-     */
-    @Override
-    public String setActivOrHang(String processDefinitionId, String type) {
-        String result = "无操作";
-        switch (type){
-            case "active":
-                repositoryService.activateProcessDefinitionById(processDefinitionId,true,null);
-                result = "已激活ID为【"+processDefinitionId+"】的流程模型实例";
-                break;
-            case "suspend":
-                repositoryService.suspendProcessDefinitionById(processDefinitionId,true,null);
-                result = "已挂起ID为【"+processDefinitionId+"】的流程模型实例";
-                break;
-            default:
-                break;
-        }
-        return result;
-    }
-
-
-    /**
-     * 根据上传文件类型对应实现不同方式的流程部署
-     * @param inputStream 文件输入流
-     * @param fileName 文件名
-     * @return 文件部署流程
-     */
-    public Deployment getDeplymentByType(InputStream inputStream,String fileName){
-        Deployment deployment;
-        String type = FilenameUtils.getExtension(fileName);
-        switch (type){
-            case "bpmn":
-                String baseName = FilenameUtils.getBaseName(fileName);
-                deployment = repositoryService.createDeployment().addInputStream(baseName+"."+BPMN20_XML,inputStream).deploy();
-                break;
-            case "png":
-                deployment = repositoryService.createDeployment().addInputStream(fileName,inputStream).deploy();
-                break;
-            case "zip":
-            case "bar":
-                ZipInputStream zipInputStream = new ZipInputStream(inputStream);
-                deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();
-                break;
-            default:
-                throw exception(FILE_UPLOAD_FAILED);
-        }
-        return deployment;
-    }
-}

+ 0 - 26
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/TaskService.java

@@ -1,26 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.workflow;
-
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import java.util.List;
-
-// TODO @芋艿:前缀,注释
-public interface TaskService {
-
-    PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO);
-
-    void claimTask(String taskId);
-
-    void getTaskHistory(String taskId);
-
-    void completeTask(TaskReqVO taskReq);
-
-//    void flowImage(String taskId, HttpServletResponse response);
-    TaskHandleVO getTaskSteps(TaskQueryReqVO taskQuery);
-
-    List<TaskStepVO> getHistorySteps(String processInstanceId);
-
-    TodoTaskRespVO getTaskFormKey(TaskQueryReqVO taskQuery);
-
-}

+ 0 - 266
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/impl/TaskServiceImpl.java

@@ -1,266 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.impl;
-
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
-import cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.TaskService;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.security.core.LoginUser;
-import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
-import com.google.common.collect.ImmutableMap;
-import org.activiti.api.runtime.shared.query.Page;
-import org.activiti.api.runtime.shared.query.Pageable;
-import org.activiti.api.task.model.Task;
-import org.activiti.api.task.model.builders.ClaimTaskPayloadBuilder;
-import org.activiti.api.task.model.builders.TaskPayloadBuilder;
-import org.activiti.api.task.runtime.TaskRuntime;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.history.HistoricActivityInstance;
-import org.activiti.engine.history.HistoricProcessInstance;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.activiti.engine.task.Comment;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-@Service
-public class TaskServiceImpl implements TaskService {
-
-    @Resource
-    private  TaskRuntime taskRuntime;
-
-    @Resource
-    private org.activiti.engine.TaskService activitiTaskService;
-
-    @Resource
-    private HistoryService  historyService;
-
-    @Resource
-    private RepositoryService repositoryService;
-
-    @Resource
-    private OaLeaveMapper leaveMapper;
-
-    private static Map<String,String>  taskVariable =  ImmutableMap.<String,String>builder()
-                    .put("deptLeaderVerify","deptLeaderApproved")
-                    .put("hrVerify","hrApproved")
-                    .build();
-
-    public TaskServiceImpl() {
-
-    }
-
-    @Override
-    public PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO) {
-        final LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
-        // TODO @jason:封装一个方法,用于转换成 activiti 的分页对象
-        final Pageable pageable = Pageable.of((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(), pageReqVO.getPageSize());
-        Page<Task> pageTasks = taskRuntime.tasks(pageable);
-        // TODO @jason:convert 里转换
-        List<Task> tasks = pageTasks.getContent();
-        int totalItems = pageTasks.getTotalItems();
-        final List<TodoTaskRespVO> respVOList = tasks.stream().map(task -> {
-            TodoTaskRespVO respVO = new TodoTaskRespVO();
-            respVO.setId(task.getId());
-            final ProcessDefinition definition = repositoryService.getProcessDefinition(task.getProcessDefinitionId());
-            respVO.setProcessName(definition.getName());
-            respVO.setProcessKey(definition.getKey());
-            respVO.setBusinessKey(task.getBusinessKey());
-            respVO.setStatus(task.getAssignee() == null ? 1 : 2);
-            return respVO;
-        }).collect(Collectors.toList());
-        // TODO @jason:要注意泛型哈。
-        return new PageResult(respVOList, Long.valueOf(totalItems)); // TODO @jason:(long) 转换即可
-    }
-
-
-    @Override
-    public void claimTask(String taskId) {
-        taskRuntime.claim(new ClaimTaskPayloadBuilder()
-                                .withTaskId(taskId)
-                                .withAssignee(SecurityFrameworkUtils.getLoginUser().getUsername())
-                                .build());
-    }
-
-    @Override
-    public void getTaskHistory(String taskId) {
-        final List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().
-                processInstanceId("8e2801fc-1a38-11ec-98ce-74867a13730f").list();
-    }
-
-    // TODO @jason:一个方法里,会有多个方法的调用,最好写下对应的注释。这样容易理解
-    @Override
-    @Transactional
-    public void completeTask(TaskReqVO taskReq) {
-        final Task task = taskRuntime.task(taskReq.getTaskId());
-
-        final Map<String, Object> variables = taskReq.getVariables();
-
-        activitiTaskService.addComment(taskReq.getTaskId(), task.getProcessInstanceId(), taskReq.getComment());
-
-        taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskReq.getTaskId())
-                .withVariables(taskReq.getVariables())
-                .build());
-
-//        if(variables.containsValue(Boolean.FALSE)){
-//            final String businessKey = task.getBusinessKey();
-//            UpdateWrapper<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
-//            updateWrapper.eq("id", Long.valueOf(businessKey));
-//            OaLeaveDO updateDo = new OaLeaveDO();
-//            updateDo.setStatus(2);
-//            leaveMapper.update(updateDo, updateWrapper);
-//        }
-
-    }
-
-//    @Override
-//    public void flowImage(String taskId, HttpServletResponse response) {
-//
-//        final Task task = taskRuntime.task(taskId);
-//        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
-//        final Process process = bpmnModel.getMainProcess();
-//        ProcessDefinitionEntity processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
-//        List<String> activeActivityIds = runtimeService.getActiveActivityIds(executionId);
-//        List<String> highLightedFlows = getHighLightedFlows(processDefinition, processInstance.getId());
-//        ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
-//        InputStream imageStream =diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds, highLightedFlows);
-//
-//        // 输出资源内容到相应对象
-//        byte[] b = new byte[1024];
-//        int len;
-//        while ((len = imageStream.read(b, 0, 1024)) != -1) {
-//            response.getOutputStream().write(b, 0, len);
-//        }
-//    }
-
-    @Override
-    public TaskHandleVO getTaskSteps(TaskQueryReqVO taskQuery) {
-        TaskHandleVO handleVO = new TaskHandleVO();
-
-//        String processKey = taskQuery.getProcessKey();
-//        if ("leave".equals(processKey)) {
-//            String businessKey = taskQuery.getBusinessKey();
-//            final OaLeaveDO leave = leaveMapper.selectById(Long.valueOf(businessKey));
-//            handleVO.setFormObject( OaLeaveConvert.INSTANCE.convert(leave));
-//        }
-
-//
-//        final String taskDefKey = task.getTaskDefinitionKey();
-//        final String variableName = Optional.ofNullable(taskVariable.get(taskDefKey)).orElse("");
-//        handleVO.setTaskVariable(variableName);
-        final Task task = taskRuntime.task(taskQuery.getTaskId());
-
-        List<TaskStepVO> steps = getTaskSteps(task.getProcessInstanceId());
-
-        handleVO.setHistoryTask(steps);
-        return handleVO;
-    }
-
-
-    private List<TaskStepVO> getTaskSteps(String processInstanceId) {
-        // 获得已完成的活动
-        List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery()
-                .processInstanceId(processInstanceId)
-                .activityType("userTask")
-                .finished()
-                .orderByHistoricActivityInstanceStartTime().asc().list();
-        // 获得对应的步骤
-        List<TaskStepVO> steps = new ArrayList<>();
-        finished.forEach(instance -> {
-            // TODO @jason:放到 convert 里
-            TaskStepVO step = new TaskStepVO();
-            step.setStepName(instance.getActivityName());
-            step.setStartTime(instance.getStartTime());
-            step.setEndTime(instance.getEndTime());
-            step.setAssignee(instance.getAssignee());
-            step.setStatus(1);
-            // TODO @jason:一般判数组为空,使用 CollUtil.isEmpty 会好点哈。另外,null 时候,不用填写 "" 的哈
-            List<Comment> comments = activitiTaskService.getTaskComments(instance.getTaskId());
-            if (comments.size() > 0) {
-                step.setComment(comments.get(0).getFullMessage());
-            } else {
-                step.setComment("");
-            }
-            steps.add(step);
-        });
-
-        // 获得未完成的活动
-        List<HistoricActivityInstance> unfinished = historyService
-                .createHistoricActivityInstanceQuery()
-                .processInstanceId(processInstanceId)
-                .activityType("userTask")
-                .unfinished().list();
-        // 获得对应的步骤
-        // TODO @json:其实已完成和未完成,它们的 convert 的逻辑,是一致的
-        for (HistoricActivityInstance instance : unfinished) {
-            TaskStepVO step = new TaskStepVO();
-            step.setStepName(instance.getActivityName());
-            step.setStartTime(instance.getStartTime());
-            step.setEndTime(instance.getEndTime());
-            step.setAssignee(Optional.ofNullable(instance.getAssignee()).orElse(""));
-            step.setComment("");
-            step.setStatus(0);
-            steps.add(step);
-        }
-        return steps;
-    }
-
-
-    @Override
-    public List<TaskStepVO> getHistorySteps(String processInstanceId) {
-        return getTaskSteps(processInstanceId);
-    }
-
-    @Override
-    public TodoTaskRespVO getTaskFormKey(TaskQueryReqVO taskQuery) {
-        final Task task = taskRuntime.task(taskQuery.getTaskId());
-        // 转换结果
-        TodoTaskRespVO respVO = new TodoTaskRespVO();
-        respVO.setFormKey(task.getFormKey());
-        respVO.setBusinessKey(task.getBusinessKey());
-        respVO.setId(task.getId());
-        return respVO;
-    }
-
-//    private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId) {
-//
-//        List<String> highLightedFlows = new ArrayList<String>();
-//        List<HistoricActivityInstance> historicActivityInstances = historyService
-//                .createHistoricActivityInstanceQuery()
-//                .processInstanceId(processInstanceId)
-//                .orderByHistoricActivityInstanceStartTime().asc().list();
-//
-//        List<String> historicActivityInstanceList = new ArrayList<String>();
-//        for (HistoricActivityInstance hai : historicActivityInstances) {
-//            historicActivityInstanceList.add(hai.getActivityId());
-//        }
-
-//        // add current activities to list
-//        List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
-//        historicActivityInstanceList.addAll(highLightedActivities);
-
-        // activities and their sequence-flows
-//        for (ActivityImpl activity : processDefinition.getActivities()) {
-//            int index = historicActivityInstanceList.indexOf(activity.getId());
-//
-//            if (index >= 0 && index + 1 < historicActivityInstanceList.size()) {
-//                List<PvmTransition> pvmTransitionList = activity
-//                        .getOutgoingTransitions();
-//                for (PvmTransition pvmTransition : pvmTransitionList) {
-//                    String destinationFlowId = pvmTransition.getDestination().getId();
-//                    if (destinationFlowId.equals(historicActivityInstanceList.get(index + 1))) {
-//                        highLightedFlows.add(pvmTransition.getId());
-//                    }
-//                }
-//            }
-//        }
-//        return highLightedFlows;
-//    }
-
-}

+ 58 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/BpmProcessDefinitionController.java

@@ -0,0 +1,58 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Api(tags = "流程定义")
+@RestController
+@RequestMapping("/bpm/process-definition")
+@Validated
+public class BpmProcessDefinitionController {
+
+    @Resource
+    private BpmProcessDefinitionService bpmDefinitionService;
+
+    @GetMapping ("/page")
+    @ApiOperation(value = "获得流程定义分页")
+    @PreAuthorize("@ss.hasPermission('bpm:model:query')") // 暂时使用 model 的权限标识
+    public CommonResult<PageResult<BpmProcessDefinitionPageItemRespVO>> getProcessDefinitionPage(
+            BpmProcessDefinitionPageReqVO pageReqVO) {
+        return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO));
+    }
+
+    // TODO 芋艿:需要重写该方法
+    @GetMapping(value = "/getStartForm")
+    public CommonResult<String> getStartForm(@RequestParam("processKey") String processKey){
+//        final ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
+//                processDefinitionKey(processKey).latestVersion().singleResult();
+//        processRuntime.processDefinition(processDefinition.getId()).getFormKey();
+        // TODO 这样查似乎有问题??, 暂时写死
+        return success("/flow/leave/apply");
+    }
+
+    @GetMapping ("/get-bpmn-xml")
+    @ApiOperation(value = "获得流程定义的 BPMN XML")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
+    @PreAuthorize("@ss.hasPermission('bpm:model:query')") // 暂时使用 model 的权限标识
+    public CommonResult<String> getProcessDefinitionBpmnXML(@RequestParam("id") String id) {
+        String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id);
+        return success(bpmnXML);
+    }
+
+}

+ 24 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/BpmProcessDefinitionPageItemRespVO.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.Date;
+
+@ApiModel("流程定义的分页的每一项 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmProcessDefinitionPageItemRespVO extends BpmProcessDefinitionRespVO {
+
+    @ApiModelProperty(value = "表单名字", example = "请假表单")
+    private String formName;
+
+    @ApiModelProperty(value = "部署时间", required = true)
+    private Date deploymentTime;
+
+
+}

+ 19 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/BpmProcessDefinitionPageReqVO.java

@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo;
+
+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;
+
+@Data
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+@ApiModel("流程定义分页 Request VO")
+public class BpmProcessDefinitionPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "标识", example = "process1641042089407", notes = "精准匹配")
+    private String key;
+
+}

+ 36 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/BpmProcessDefinitionRespVO.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+@ApiModel("流程定义 Response VO")
+@Data
+public class BpmProcessDefinitionRespVO {
+
+    @ApiModelProperty(value = "编号", required = true, example = "1024")
+    private String id;
+
+    @ApiModelProperty(value = "版本", required = true, example = "1")
+    private Integer version;
+
+    @ApiModelProperty(value = "流程名称", required = true, example = "芋道")
+    @NotEmpty(message = "流程名称不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "流程描述", example = "我是描述")
+    private String description;
+
+    @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1")
+    @NotEmpty(message = "流程分类不能为空")
+    private String category;
+
+    @ApiModelProperty(value = "表单编号", example = "1024")
+    private Long formId;
+
+    @ApiModelProperty(value = "中断状态", required = true, example = "1", notes = "参见 SuspensionState 枚举")
+    private Integer suspensionState;
+
+}

+ 79 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/BpmFormController.java

@@ -0,0 +1,79 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.form;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.*;
+import cn.iocoder.yudao.adminserver.modules.bpm.convert.form.BpmFormConvert;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Api(tags = "动态表单")
+@RestController
+@RequestMapping("/bpm/form")
+@Validated
+public class BpmFormController {
+
+    @Resource
+    private BpmFormService formService;
+
+    @PostMapping("/create")
+    @ApiOperation("创建动态表单")
+    @PreAuthorize("@ss.hasPermission('bpm:form:create')")
+    public CommonResult<Long> createForm(@Valid @RequestBody BpmFormCreateReqVO createReqVO) {
+        return success(formService.createForm(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("更新动态表单")
+    @PreAuthorize("@ss.hasPermission('bpm:form:update')")
+    public CommonResult<Boolean> updateForm(@Valid @RequestBody BpmFormUpdateReqVO updateReqVO) {
+        formService.updateForm(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除动态表单")
+    @ApiImplicitParam(name = "id", value = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('bpm:form:delete')")
+    public CommonResult<Boolean> deleteForm(@RequestParam("id") Long id) {
+        formService.deleteForm(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @ApiOperation("获得动态表单")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('bpm:form:query')")
+    public CommonResult<BpmFormRespVO> getForm(@RequestParam("id") Long id) {
+        BpmFormDO form = formService.getForm(id);
+        return success(BpmFormConvert.INSTANCE.convert(form));
+    }
+
+    @GetMapping("/list-all-simple")
+    @ApiOperation(value = "获得动态表单的精简列表", notes = "用于表单下拉框")
+    public CommonResult<List<BpmFormSimpleRespVO>> getSimpleForms() {
+        List<BpmFormDO> list = formService.getFormList();
+        return success(BpmFormConvert.INSTANCE.convertList2(list));
+    }
+
+    @GetMapping("/page")
+    @ApiOperation("获得动态表单分页")
+    @PreAuthorize("@ss.hasPermission('bpm:form:query')")
+    public CommonResult<PageResult<BpmFormRespVO>> getFormPage(@Valid BpmFormPageReqVO pageVO) {
+        PageResult<BpmFormDO> pageResult = formService.getFormPage(pageVO);
+        return success(BpmFormConvert.INSTANCE.convertPage(pageResult));
+    }
+
+}

+ 25 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormBaseVO.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+/**
+* 动态表单 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class BpmFormBaseVO {
+
+    @ApiModelProperty(value = "表单名称", required = true, example = "芋道")
+    @NotNull(message = "表单名称不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "表单状态", required = true, notes = "参见 CommonStatusEnum 枚举", example = "1")
+    @NotNull(message = "表单状态不能为空")
+    private Integer status;
+
+    @ApiModelProperty(value = "备注", example = "我是备注")
+    private String remark;
+
+}

+ 23 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormCreateReqVO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@ApiModel("动态表单创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmFormCreateReqVO extends BpmFormBaseVO {
+
+    @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串")
+    @NotNull(message = "表单的配置不能为空")
+    private String conf;
+
+    @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组")
+    @NotNull(message = "表单项的数组不能为空")
+    private List<String> fields;
+
+}

+ 19 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormPageReqVO.java

@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
+
+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;
+
+@ApiModel("动态表单分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmFormPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "表单名称", example = "芋道")
+    private String name;
+
+}

+ 32 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormRespVO.java

@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+
+@ApiModel("动态表单 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmFormRespVO extends BpmFormBaseVO {
+
+    @ApiModelProperty(value = "表单编号", required = true, example = "1024")
+    private Long id;
+    @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串")
+    @NotNull(message = "表单的配置不能为空")
+    private String conf;
+
+    @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组")
+    @NotNull(message = "表单项的数组不能为空")
+    private List<String> fields;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}

+ 17 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormSimpleRespVO.java

@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@ApiModel("流程表单精简 Response VO")
+@Data
+public class BpmFormSimpleRespVO {
+
+    @ApiModelProperty(value = "表单编号", required = true, example = "1024")
+    private Long id;
+
+    @ApiModelProperty(value = "表单名称", required = true, example = "芋道")
+    private String name;
+
+}

+ 26 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormUpdateReqVO.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+import java.util.List;
+
+@ApiModel("动态表单更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmFormUpdateReqVO extends BpmFormBaseVO {
+
+    @ApiModelProperty(value = "表单编号", required = true, example = "1024")
+    @NotNull(message = "表单编号不能为空")
+    private Long id;
+
+    @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串")
+    @NotNull(message = "表单的配置不能为空")
+    private String conf;
+
+    @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组")
+    @NotNull(message = "表单项的数组不能为空")
+    private List<String> fields;
+
+}

+ 97 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/BpmModelController.java

@@ -0,0 +1,97 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.model;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo.*;
+import cn.iocoder.yudao.adminserver.modules.bpm.convert.model.BpmModelConvert;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.model.BpmModelService;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.io.IoUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.io.IOException;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Api(tags = "流程模型")
+@RestController
+@RequestMapping("/bpm/model")
+@Validated
+public class BpmModelController {
+
+    @Resource
+    private BpmModelService bpmModelService;
+
+    @GetMapping("/page")
+    @ApiOperation(value = "获得模型分页")
+    public CommonResult<PageResult<BpmModelPageItemRespVO>> getModelPage(ModelPageReqVO pageVO) {
+        return success(bpmModelService.getModelPage(pageVO));
+    }
+
+    @GetMapping("/get")
+    @ApiOperation("获得模型")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
+    @PreAuthorize("@ss.hasPermission('bpm:model:query')")
+    public CommonResult<BpmModelRespVO> getModel(@RequestParam("id") String id) {
+        BpmModelRespVO model = bpmModelService.getModel(id);
+        return success(model);
+    }
+
+    @PostMapping("/create")
+    @ApiOperation(value = "新建模型")
+    @PreAuthorize("@ss.hasPermission('bpm:model:create')")
+    public CommonResult<String> createModel(@Valid @RequestBody BpmModelCreateReqVO createRetVO) {
+        return success(bpmModelService.createModel(createRetVO));
+    }
+
+    @PostMapping("/import")
+    @ApiOperation(value = "导入模型")
+    @PreAuthorize("@ss.hasPermission('bpm:model:import')")
+    public CommonResult<String> importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException {
+        BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO);
+        // 读取文件
+        createReqVO.setBpmnXml(IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false));
+        return success(bpmModelService.createModel(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation(value = "修改模型")
+    @PreAuthorize("@ss.hasPermission('bpm:model:update')")
+    public CommonResult<Boolean> updateModel(@Valid @RequestBody BpmModelUpdateReqVO modelVO) {
+        bpmModelService.updateModel(modelVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除模型")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
+    @PreAuthorize("@ss.hasPermission('bpm:model:delete')")
+    public CommonResult<Boolean> deleteModel(@RequestParam("id") String id) {
+        bpmModelService.deleteModel(id);
+        return success(true);
+    }
+
+    @PostMapping("/deploy")
+    @ApiOperation(value = "部署模型")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
+    @PreAuthorize("@ss.hasPermission('bpm:model:deploy')")
+    public CommonResult<Boolean> deployModel(@RequestParam("id") String id) {
+        bpmModelService.deployModel(id);
+        return success(true);
+    }
+
+    @PutMapping("/update-state")
+    @ApiOperation(value = "修改模型的状态", notes = "实际更新的部署的流程定义的状态")
+    @PreAuthorize("@ss.hasPermission('bpm:model:update')")
+    public CommonResult<Boolean> updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) {
+        bpmModelService.updateModelState(reqVO.getId(), reqVO.getState());
+        return success(true);
+    }
+
+}

+ 22 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModeImportReqVO.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.constraints.NotNull;
+
+@ApiModel("流程模型的导入 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmModeImportReqVO extends BpmModelBaseVO {
+
+    @ApiModelProperty(value = "BPMN 文件", required = true)
+    @NotNull(message = "BPMN 文件不能为空")
+    private MultipartFile bpmnFile;
+
+}

+ 33 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelBaseVO.java

@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+* 流程模型 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class BpmModelBaseVO {
+
+    @ApiModelProperty(value = "流程标识", required = true, example = "process_yudao")
+    @NotEmpty(message = "流程标识不能为空")
+    private String key;
+
+    @ApiModelProperty(value = "流程名称", required = true, example = "芋道")
+    @NotEmpty(message = "流程名称不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "流程描述", example = "我是描述")
+    private String description;
+
+    @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1")
+    @NotEmpty(message = "流程分类不能为空")
+    private String category;
+
+    @ApiModelProperty(value = "表单编号", example = "1024")
+    private Long formId;
+
+}

+ 21 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelCreateReqVO.java

@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.constraints.NotEmpty;
+
+@ApiModel("流程模型的创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmModelCreateReqVO extends BpmModelBaseVO {
+
+    @ApiModelProperty(value = "BPMN XML", required = true)
+    @NotEmpty(message = "BPMN XML 不能为空")
+    private String bpmnXml;
+
+}

+ 49 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelPageItemRespVO.java

@@ -0,0 +1,49 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.Date;
+
+@ApiModel("流程模型的分页的每一项 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmModelPageItemRespVO extends BpmModelBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true, example = "1024")
+    private String id;
+
+    @ApiModelProperty(value = "表单名字", example = "请假表单")
+    private String formName;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+    /**
+     * 最新部署的流程定义
+     */
+    private ProcessDefinition processDefinition;
+
+    @ApiModel("流程定义")
+    @Data
+    public static class ProcessDefinition {
+
+        @ApiModelProperty(value = "编号", required = true, example = "1024")
+        private String id;
+
+        @ApiModelProperty(value = "版本", required = true, example = "1")
+        private Integer version;
+
+        @ApiModelProperty(value = "部署时间", required = true)
+        private Date deploymentTime;
+
+        @ApiModelProperty(value = "中断状态", required = true, example = "1", notes = "参见 SuspensionState 枚举")
+        private Integer suspensionState;
+
+    }
+
+}

+ 26 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelRespVO.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.Date;
+
+@ApiModel("流程模型的创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmModelRespVO extends BpmModelBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true, example = "1024")
+    private String id;
+
+    @ApiModelProperty(value = "BPMN XML", required = true)
+    private String bpmnXml;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}

+ 25 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelUpdateReqVO.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.constraints.NotEmpty;
+
+@ApiModel("流程模型的更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BpmModelUpdateReqVO extends BpmModelBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true, example = "1024")
+    @NotEmpty(message = "编号不能为空")
+    private String id;
+
+    @ApiModelProperty(value = "BPMN XML", required = true)
+    @NotEmpty(message = "BPMN XML 不能为空")
+    private String bpmnXml;
+
+}

+ 21 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelUpdateStateReqVO.java

@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@ApiModel("流程模型更新状态 Request VO")
+@Data
+public class BpmModelUpdateStateReqVO {
+
+    @ApiModelProperty(value = "编号", required = true, example = "1024")
+    @NotNull(message = "编号不能为空")
+    private String id;
+
+    @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SuspensionState 枚举")
+    @NotNull(message = "状态不能为空")
+    private Integer state;
+
+}

+ 26 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/ModelPageReqVO.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo;
+
+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;
+
+
+@ApiModel("流程模型分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class ModelPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "标识", example = "process1641042089407", notes = "精准匹配")
+    private String key;
+
+    @ApiModelProperty(value = "名字", example = "芋道", notes = "模糊匹配")
+    private String name;
+
+    @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1")
+    private String category;
+
+}

+ 32 - 34
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/OaLeaveController.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/OALeaveController.java

@@ -1,9 +1,9 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa;
 
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
-import cn.iocoder.yudao.adminserver.modules.activiti.convert.oa.OaLeaveConvert;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
-import cn.iocoder.yudao.adminserver.modules.activiti.service.oa.OaLeaveService;
+import cn.iocoder.yudao.adminserver.modules.bpm.convert.oa.OALeaveConvert;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.oa.OALeaveService;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.*;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@@ -26,37 +26,35 @@ import java.util.List;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
 
-// TODO @jason:Oa=》OA 会不会好点,名词缩写哈
+
 @Api(tags = "请假申请")
 @RestController
 @RequestMapping("/oa/leave")
 @Validated
-public class OaLeaveController {
+public class OALeaveController {
 
     @Resource
-    private OaLeaveService leaveService;
-
-    @PostMapping("/create")
-    @ApiOperation("创建请假申请")
-    @PreAuthorize("@ss.hasPermission('oa:leave:create')")
-    public CommonResult<Long> createLeave(@Valid @RequestBody OaLeaveCreateReqVO createReqVO) {
-        // TODO @芋艿:processKey 自己去理解下。不过得把 leave 变成枚举
-        createReqVO.setProcessKey("leave");
-        return success(leaveService.createLeave(createReqVO));
-    }
+    private OALeaveService leaveService;
+
+
 
     @PostMapping("/form-key/create")
     @ApiOperation("创建外置请假申请")
-    public CommonResult<Long> createFormKeyLeave(@Valid @RequestBody OaLeaveCreateReqVO createReqVO) {
-        // TODO @芋艿:processKey 自己去理解下。不过得把 formkey 变成枚举
-        createReqVO.setProcessKey("leave-formkey");
+    public CommonResult<Long> createFormKeyLeave(@Valid @RequestBody OALeaveCreateReqVO createReqVO) {
+        // processKey 前台传入
         return success(leaveService.createLeave(createReqVO));
     }
 
+    @GetMapping("/getLeaveApplyMembers")
+    @ApiOperation("获取本人请假申请流程中审批人员,可先检查这些人员是否存在")
+    public CommonResult<OALeaveApplyMembersVO> getLeaveApplyMembers() {
+        return success(leaveService.getLeaveApplyMembers());
+    }
+
     @PutMapping("/update")
     @ApiOperation("更新请假申请")
     @PreAuthorize("@ss.hasPermission('oa:leave:update')")
-    public CommonResult<Boolean> updateLeave(@Valid @RequestBody OaLeaveUpdateReqVO updateReqVO) {
+    public CommonResult<Boolean> updateLeave(@Valid @RequestBody OALeaveUpdateReqVO updateReqVO) {
         leaveService.updateLeave(updateReqVO);
         return success(true);
     }
@@ -74,41 +72,41 @@ public class OaLeaveController {
     @ApiOperation("获得请假申请")
     @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
     @PreAuthorize("@ss.hasPermission('oa:leave:query')")
-    public CommonResult<OaLeaveRespVO> getLeave(@RequestParam("id") Long id) {
-        OaLeaveDO leave = leaveService.getLeave(id);
-        return success(OaLeaveConvert.INSTANCE.convert(leave));
+    public CommonResult<OALeaveRespVO> getLeave(@RequestParam("id") Long id) {
+        OALeaveDO leave = leaveService.getLeave(id);
+        return success(OALeaveConvert.INSTANCE.convert(leave));
     }
 
     @GetMapping("/list")
     @ApiOperation("获得请假申请列表")
     @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
     @PreAuthorize("@ss.hasPermission('oa:leave:query')")
-    public CommonResult<List<OaLeaveRespVO>> getLeaveList(@RequestParam("ids") Collection<Long> ids) {
-        List<OaLeaveDO> list = leaveService.getLeaveList(ids);
-        return success(OaLeaveConvert.INSTANCE.convertList(list));
+    public CommonResult<List<OALeaveRespVO>> getLeaveList(@RequestParam("ids") Collection<Long> ids) {
+        List<OALeaveDO> list = leaveService.getLeaveList(ids);
+        return success(OALeaveConvert.INSTANCE.convertList(list));
     }
 
     @GetMapping("/page")
     @ApiOperation("获得请假申请分页")
     @PreAuthorize("@ss.hasPermission('oa:leave:query')")
-    public CommonResult<PageResult<OaLeaveRespVO>> getLeavePage(@Valid OaLeavePageReqVO pageVO) {
+    public CommonResult<PageResult<OALeaveRespVO>> getLeavePage(@Valid OALeavePageReqVO pageVO) {
         //值查询自己申请请假
         // TODO @芋艿:这里的传值,到底前端搞,还是后端搞。
         pageVO.setUserId(SecurityFrameworkUtils.getLoginUser().getUsername());
-        PageResult<OaLeaveDO> pageResult = leaveService.getLeavePage(pageVO);
-        return success(OaLeaveConvert.INSTANCE.convertPage(pageResult));
+        PageResult<OALeaveDO> pageResult = leaveService.getLeavePage(pageVO);
+        return success(OALeaveConvert.INSTANCE.convertPage(pageResult));
     }
 
     @GetMapping("/export-excel")
     @ApiOperation("导出请假申请 Excel")
     @PreAuthorize("@ss.hasPermission('oa:leave:export')")
     @OperateLog(type = EXPORT)
-    public void exportLeaveExcel(@Valid OaLeaveExportReqVO exportReqVO,
+    public void exportLeaveExcel(@Valid OALeaveExportReqVO exportReqVO,
               HttpServletResponse response) throws IOException {
-        List<OaLeaveDO> list = leaveService.getLeaveList(exportReqVO);
+        List<OALeaveDO> list = leaveService.getLeaveList(exportReqVO);
         // 导出 Excel
-        List<OaLeaveExcelVO> datas = OaLeaveConvert.INSTANCE.convertList02(list);
-        ExcelUtils.write(response, "请假申请.xls", "数据", OaLeaveExcelVO.class, datas);
+        List<OALeaveExcelVO> datas = OALeaveConvert.INSTANCE.convertList02(list);
+        ExcelUtils.write(response, "请假申请.xls", "数据", OALeaveExcelVO.class, datas);
     }
 
 }

+ 25 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveApplyMembersVO.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@ApiModel("请假申请审批人员 Response VO")
+@Data
+@Builder
+@EqualsAndHashCode
+@ToString
+public class OALeaveApplyMembersVO {
+
+    @ApiModelProperty(value = "部门的hr")
+    private String hr;
+
+    @ApiModelProperty(value = "部门的项目经理")
+    private String pm;
+
+    @ApiModelProperty(value = "部门的部门经理")
+    private String bm;
+}

+ 2 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveBaseVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveBaseVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
 
 import lombok.*;
 import java.util.*;
@@ -13,7 +13,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
 */
 @Data
-public class OaLeaveBaseVO {
+public class OALeaveBaseVO {
 
     @ApiModelProperty(value = "流程id")
     private String processInstanceId;

+ 23 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveCreateReqVO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+
+import java.util.Map;
+
+@ApiModel("请假申请创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class OALeaveCreateReqVO extends OALeaveBaseVO {
+
+    /**
+     * 对应 bpmn 文件 <process> 的 id
+     */
+    @ApiModelProperty(value = "流程key")
+    private String processKey;
+
+
+    @ApiModelProperty(value = "流程用户任务的变量")
+    private Map<String,Object> taskVariables;
+}

+ 2 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExcelVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveExcelVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
 
 import lombok.*;
 import java.util.*;
@@ -12,7 +12,7 @@ import com.alibaba.excel.annotation.ExcelProperty;
  * @author 芋艿
  */
 @Data
-public class OaLeaveExcelVO {
+public class OALeaveExcelVO {
 
     @ExcelProperty("请假表单主键")
     private Long id;

+ 2 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExportReqVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveExportReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
 
 import lombok.*;
 import java.util.*;
@@ -10,7 +10,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 
 @ApiModel(value = "请假申请 Excel 导出 Request VO", description = "参数和 OaLeavePageReqVO 是一致的")
 @Data
-public class OaLeaveExportReqVO {
+public class OALeaveExportReqVO {
 
     @ApiModelProperty(value = "流程id")
     private String processInstanceId;

+ 2 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeavePageReqVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeavePageReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
 
 import lombok.*;
 import java.util.*;
@@ -12,7 +12,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class OaLeavePageReqVO extends PageParam {
+public class OALeavePageReqVO extends PageParam {
 
     @ApiModelProperty(value = "流程id")
     private String processInstanceId;

+ 2 - 3
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveRespVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveRespVO.java

@@ -1,14 +1,13 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
 
 import lombok.*;
-import java.util.*;
 import io.swagger.annotations.*;
 
 @ApiModel("请假申请 Response VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class OaLeaveRespVO extends OaLeaveBaseVO {
+public class OALeaveRespVO extends OALeaveBaseVO {
 
     @ApiModelProperty(value = "请假表单主键", required = true)
     private Long id;

+ 2 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveUpdateReqVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/OALeaveUpdateReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -13,7 +13,7 @@ import java.util.Map;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class OaLeaveUpdateReqVO extends OaLeaveBaseVO {
+public class OALeaveUpdateReqVO extends OALeaveBaseVO {
 
     @ApiModelProperty(value = "请假表单主键", required = true)
     @NotNull(message = "请假表单主键不能为空")

+ 13 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.http

@@ -0,0 +1,13 @@
+### 请求 /login 接口 => 成功
+POST {{baseUrl}}/bpm/process-instance/create
+Content-Type: application/json
+tenant-id: 1
+Authorization: Bearer {{token}}
+
+{
+  "processDefinitionId": "leave:7:20ada39c-6c95-11ec-88b1-cacd34981f8e",
+  "variables": {
+    "a": 1,
+    "b": "2"
+  }
+}

+ 35 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.java

@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.task;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
+
+@Api(tags = "流程实例") // 流程实例,通过流程定义创建的一次“申请”
+@RestController
+@RequestMapping("/bpm/process-instance")
+@Validated
+public class BpmProcessInstanceController {
+
+    @Resource
+    private BpmProcessInstanceService processInstanceService;
+
+    @PostMapping("/create")
+    @ApiOperation("新建流程实例")
+    public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
+        return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
+    }
+
+}

+ 23 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceCreateReqVO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import java.util.Map;
+
+@ApiModel("流程实例的创建 Request VO")
+@Data
+//@EqualsAndHashCode(callSuper = true)
+//@ToString(callSuper = true)
+public class BpmProcessInstanceCreateReqVO {
+
+    @ApiModelProperty(value = "流程定义的编号", required = true, example = "1024")
+    @NotEmpty(message = "流程定义编号不能为空")
+    private String processDefinitionId;
+
+    @ApiModelProperty(value = "变量实例")
+    private Map<String, Object> variables;
+
+}

+ 6 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceMyPageReqVO.java

@@ -0,0 +1,6 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+
+public class BpmProcessInstanceMyPageReqVO extends PageParam {
+}

+ 23 - 10
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/TaskController.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/TaskController.java

@@ -1,15 +1,18 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow;
 
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
-import cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.TaskService;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.*;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
 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 io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
+import java.io.IOException;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -21,40 +24,50 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 public class TaskController {
 
     @Resource
-    private TaskService taskService;
+    private BpmTaskService bpmTaskService;
 
     @GetMapping("/todo/page")
     @ApiOperation("获取待办任务分页")
     public CommonResult<PageResult<TodoTaskRespVO>> getTodoTaskPage(@Valid TodoTaskPageReqVO pageVO) {
-        return success(taskService.getTodoTaskPage(pageVO));
+        return success(bpmTaskService.getTodoTaskPage(pageVO));
     }
 
     @GetMapping("/claim")
     @ApiOperation("签收任务")
     public CommonResult<Boolean> claimTask(@RequestParam("id") String taskId) {
-        taskService.claimTask(taskId);
+        bpmTaskService.claimTask(taskId);
         return success(true);
     }
 
     @PostMapping("/task-steps")
     public CommonResult<TaskHandleVO> getTaskSteps(@RequestBody TaskQueryReqVO taskQuery) {
-        return success(taskService.getTaskSteps(taskQuery));
+        return success(bpmTaskService.getTaskSteps(taskQuery));
     }
 
     @PostMapping("/formKey")
     public CommonResult<TodoTaskRespVO> getTaskFormKey(@RequestBody TaskQueryReqVO taskQuery) {
-        return success(taskService.getTaskFormKey(taskQuery));
+        return success(bpmTaskService.getTaskFormKey(taskQuery));
     }
 
     @PostMapping("/complete")
     public CommonResult<Boolean> complete(@RequestBody TaskReqVO taskReq) {
-        taskService.completeTask(taskReq);
+        bpmTaskService.completeTask(taskReq);
         return success(true);
     }
 
     @GetMapping("/process/history-steps")
     public CommonResult<List<TaskStepVO>> getHistorySteps(@RequestParam("id") String processInstanceId) {
-        return success(taskService.getHistorySteps(processInstanceId));
+        return success(bpmTaskService.getHistorySteps(processInstanceId));
+    }
+
+    /**
+     * 返回高亮的流转图SVG
+     * @param processInstanceId 流程Id
+     */
+    @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());
     }
 
 }

+ 24 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/FileResp.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo;
+
+import lombok.Data;
+
+// TODO @Li:1)改成 HighlightImgRespVO 吧。2)swagger 注解要补充;3)fileByte => fileContent
+/**
+ * 文件输出类
+ *
+ * @author yunlongn
+ */
+@Data
+public class FileResp {
+
+    /**
+     * 文件名字
+     */
+    private String fileName;
+
+    /**
+     * 文件输出流
+     */
+    private byte[] fileByte;
+
+}

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskHandleVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskHandleVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo;
 
 import lombok.Data;
 import lombok.ToString;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskQueryReqVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskQueryReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo;
 
 import lombok.Data;
 import lombok.ToString;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskReqVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo;
 
 import lombok.Data;
 import lombok.ToString;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskStepVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TaskStepVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo;
 
 import lombok.Data;
 import lombok.ToString;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskPageReqVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TodoTaskPageReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import io.swagger.annotations.ApiModel;

+ 6 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskRespVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/workflow/vo/TodoTaskRespVO.java

@@ -1,8 +1,7 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo;
 
 import io.swagger.annotations.ApiModel;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
 @ApiModel("待办任务 Response VO")
@@ -10,8 +9,13 @@ import lombok.ToString;
 @ToString
 public class TodoTaskRespVO {
 
+    // TODO @jason:swagger 注解。这样接口文档才完整哈
+
     private String id;
 
+
+    private String processInstanceId;
+
     /**
      * 1:未签收
      * 2:已签收

+ 58 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmDefinitionConvert.java

@@ -0,0 +1,58 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import org.activiti.engine.impl.persistence.entity.SuspensionState;
+import org.activiti.engine.repository.Deployment;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Bpm 流程定义的 Convert
+ *
+ * @author yunlong.li
+ */
+@Mapper
+public interface BpmDefinitionConvert {
+
+    BpmDefinitionConvert INSTANCE = Mappers.getMapper(BpmDefinitionConvert.class);
+
+    default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap,
+                               Map<String, BpmProcessDefinitionDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) {
+        return CollectionUtils.convertList(list, definition -> {
+            Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null;
+            BpmProcessDefinitionDO definitionDO = processDefinitionDOMap.get(definition.getId());
+            BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null;
+            return convert(definition, deployment, definitionDO, form);
+        });
+    }
+
+    default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment,
+                                                       BpmProcessDefinitionDO processDefinitionDO, BpmFormDO form) {
+        BpmProcessDefinitionPageItemRespVO respVO = convert(bean);
+        respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
+        if (deployment != null) {
+            respVO.setDeploymentTime(deployment.getDeploymentTime());
+        }
+        if (form != null) {
+            respVO.setFormId(form.getId());
+            respVO.setFormName(form.getName());
+        }
+        if (processDefinitionDO != null) {
+            respVO.setDescription(processDefinitionDO.getDescription());
+        }
+        return respVO;
+    }
+
+    BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean);
+
+    BpmProcessDefinitionDO convert2(BpmDefinitionCreateReqDTO bean);
+
+}

+ 34 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/form/BpmFormConvert.java

@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.convert.form;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormRespVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormSimpleRespVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 动态表单 Convert
+ *
+ * @author 芋艿
+ */
+@Mapper
+public interface BpmFormConvert {
+
+    BpmFormConvert INSTANCE = Mappers.getMapper(BpmFormConvert.class);
+
+    BpmFormDO convert(BpmFormCreateReqVO bean);
+
+    BpmFormDO convert(BpmFormUpdateReqVO bean);
+
+    BpmFormRespVO convert(BpmFormDO bean);
+
+    List<BpmFormSimpleRespVO> convertList2(List<BpmFormDO> list);
+
+    PageResult<BpmFormRespVO> convertPage(PageResult<BpmFormDO> page);
+
+}

+ 118 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/model/BpmModelConvert.java

@@ -0,0 +1,118 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.convert.model;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo.*;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.model.dto.BpmModelMetaInfoRespDTO;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import org.activiti.engine.impl.persistence.entity.SuspensionState;
+import org.activiti.engine.repository.Deployment;
+import org.activiti.engine.repository.Model;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 流程定义 Convert
+ *
+ * @author yunlongn
+ */
+@Mapper
+public interface BpmModelConvert {
+
+    BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class);
+
+    default List<BpmModelPageItemRespVO> convertList(List<Model> list, Map<Long, BpmFormDO> formMap,
+                                                     Map<String, Deployment> deploymentMap,
+                                                     Map<String, ProcessDefinition> processDefinitionMap) {
+        return CollectionUtils.convertList(list, model -> {
+            BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+            BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null;
+            Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null;
+            ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null;
+            return convert(model, form, deployment, processDefinition);
+        });
+    }
+
+    default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) {
+        BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO();
+        modelRespVO.setId(model.getId());
+        modelRespVO.setName(model.getName());
+        modelRespVO.setKey(model.getKey());
+        modelRespVO.setCategory(model.getCategory());
+        modelRespVO.setCreateTime(model.getCreateTime());
+        BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+        if (metaInfo != null) {
+            modelRespVO.setDescription(metaInfo.getDescription());
+        }
+        if (form != null) {
+            modelRespVO.setFormId(form.getId());
+            modelRespVO.setFormName(form.getName());
+        }
+        modelRespVO.setProcessDefinition(this.convert(processDefinition));
+        if (modelRespVO.getProcessDefinition() != null) {
+            modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ?
+                    SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
+            modelRespVO.getProcessDefinition().setDeploymentTime(deployment.getDeploymentTime());
+        }
+        return modelRespVO;
+    }
+
+    default BpmModelRespVO convert(Model model) {
+        BpmModelRespVO modelRespVO = new BpmModelRespVO();
+        modelRespVO.setId(model.getId());
+        modelRespVO.setName(model.getName());
+        modelRespVO.setKey(model.getKey());
+        modelRespVO.setCategory(model.getCategory());
+        modelRespVO.setCreateTime(model.getCreateTime());
+        BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+        if (metaInfo != null) {
+            modelRespVO.setFormId(metaInfo.getFormId());
+            modelRespVO.setDescription(metaInfo.getDescription());
+        }
+        return modelRespVO;
+    }
+
+    default BpmDefinitionCreateReqDTO convert2(Model model) {
+        BpmDefinitionCreateReqDTO createReqDTO = new BpmDefinitionCreateReqDTO();
+        createReqDTO.setName(model.getName());
+        createReqDTO.setKey(model.getKey());
+        createReqDTO.setCategory(model.getCategory());
+        BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+        if (metaInfo != null) {
+            createReqDTO.setDescription(metaInfo.getDescription());
+            createReqDTO.setFormId(metaInfo.getFormId());
+        }
+        return createReqDTO;
+    }
+
+    default void copy(Model model, BpmModelCreateReqVO bean) {
+        model.setName(bean.getName());
+        model.setKey(bean.getKey());
+        model.setCategory(bean.getCategory());
+        model.setMetaInfo(JsonUtils.toJsonString(this.buildMetaInfo(bean.getDescription(), bean.getFormId())));
+    }
+
+    default void copy(Model model, BpmModelUpdateReqVO bean) {
+        model.setName(bean.getName());
+        model.setCategory(bean.getCategory());
+        model.setMetaInfo(JsonUtils.toJsonString(this.buildMetaInfo(bean.getDescription(), bean.getFormId())));
+    }
+
+    default BpmModelMetaInfoRespDTO buildMetaInfo(String description, Long formId) {
+        BpmModelMetaInfoRespDTO metaInfo = new BpmModelMetaInfoRespDTO();
+        metaInfo.setDescription(description);
+        metaInfo.setFormId(formId);
+        return metaInfo;
+    }
+
+    BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean);
+
+    BpmModelCreateReqVO convert(BpmModeImportReqVO bean);
+
+}

+ 37 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/oa/OALeaveConvert.java

@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.convert.oa;
+
+import java.util.*;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.OALeaveCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.OALeaveExcelVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.OALeaveRespVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.OALeaveUpdateReqVO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * 请假申请 Convert
+ *
+ * @author 芋艿
+ */
+@Mapper
+public interface OALeaveConvert {
+
+    OALeaveConvert INSTANCE = Mappers.getMapper(OALeaveConvert.class);
+
+    OALeaveDO convert(OALeaveCreateReqVO bean);
+
+    OALeaveDO convert(OALeaveUpdateReqVO bean);
+
+    OALeaveRespVO convert(OALeaveDO bean);
+
+    List<OALeaveRespVO> convertList(List<OALeaveDO> list);
+
+    PageResult<OALeaveRespVO> convertPage(PageResult<OALeaveDO> page);
+
+    List<OALeaveExcelVO> convertList02(List<OALeaveDO> list);
+
+}

+ 6 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/package-info.java

@@ -0,0 +1,6 @@
+/**
+ * 提供 POJO 类的实体转换
+ *
+ * 目前使用 MapStruct 框架
+ */
+package cn.iocoder.yudao.adminserver.modules.bpm.convert;

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

@@ -0,0 +1,44 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.convert.workflow;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.TaskStepVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.workflow.vo.TodoTaskRespVO;
+import org.activiti.api.task.model.Task;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.Named;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface TaskConvert {
+    TaskConvert INSTANCE = Mappers.getMapper(TaskConvert.class);
+
+    @Mappings(value = {
+            @Mapping(source = "task.id", target = "id"),
+            @Mapping(source = "task.businessKey", target = "businessKey"),
+            @Mapping(source = "task.assignee", target = "status",qualifiedByName = "convertAssigneeToStatus"),
+            @Mapping(source = "definition.name", target = "processName"),
+            @Mapping(source = "definition.key", target = "processKey"),
+            @Mapping(source = "definition.id", target = "processInstanceId")
+    })
+    TodoTaskRespVO convert(Task task, ProcessDefinition definition);
+
+    @Mappings(value = {
+            @Mapping(source = "assignee", target = "status",qualifiedByName = "convertAssigneeToStatus")
+    })
+    TodoTaskRespVO convert(Task task);
+
+    @Named("convertAssigneeToStatus")
+    default Integer convertAssigneeToStatus(String assignee) {
+        //TODO 不应该通过 assignee 定义状态  需要定义更多的状态
+        return assignee == null ?  1 :  2;
+    }
+
+    @Mappings(value = {
+            @Mapping(source = "activityName", target = "stepName"),
+            @Mapping(source = "assignee", target = "assignee")
+    })
+    TaskStepVO convert(HistoricActivityInstance instance);
+}

+ 1 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md

@@ -0,0 +1 @@
+<http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao>

+ 47 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/definition/BpmProcessDefinitionDO.java

@@ -0,0 +1,47 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+import org.activiti.engine.repository.ProcessDefinition;
+
+/**
+ * Bpm 流程定义的拓展表
+ * 主要解决 主要进行 Activiti {@link ProcessDefinition} 不支持拓展字段,所以新建拓展表
+ *
+ * @author 芋道源码
+ */
+@TableName(value = "bpm_process_definition", autoResultMap = true)
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BpmProcessDefinitionDO extends BaseDO {
+
+    /**
+     * 编号
+     */
+    @TableId
+    private Long id;
+    /**
+     * 流程定义的编号
+     *
+     * 关联 {@link ProcessDefinition#getId()}
+     */
+    private String processDefinitionId;
+    /**
+     * 描述
+     */
+    private String description;
+    /**
+     * 表单编号
+     *
+     * 关联 {@link BpmFormDO#getId()}
+     */
+    private Long formId;
+
+}

+ 7 - 7
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/dataobject/form/WfForm.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmFormDO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form;
+package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import com.baomidou.mybatisplus.annotation.TableField;
@@ -15,14 +15,14 @@ import java.util.List;
  *
  * @author 芋道源码
  */
-@TableName(value = "wf_form", autoResultMap = true)
+@TableName(value = "bpm_form", autoResultMap = true)
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class WfForm extends BaseDO {
+public class BpmFormDO extends BaseDO {
 
     /**
      * 编号
@@ -38,11 +38,11 @@ public class WfForm extends BaseDO {
      */
     private Integer status;
     /**
-     * 表单JSON
+     * 表单的配置
      */
-    private String formJson;
+    private String conf;
     /**
-     * 表单配置
+     * 表单项的数组
      *
      * 目前直接将 https://github.com/JakHuang/form-generator 生成的 JSON 串,直接保存
      * 定义:https://github.com/JakHuang/form-generator/issues/46
@@ -54,4 +54,4 @@ public class WfForm extends BaseDO {
      */
     private String remark;
 
-}
+}

+ 5 - 5
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/dataobject/form/WfFormData.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmFormDataDO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.form;
+package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import com.baomidou.mybatisplus.annotation.TableField;
@@ -15,14 +15,14 @@ import java.util.Map;
  *
  * @author 芋道源码
  */
-@TableName(value = "wf_form", autoResultMap = true)
+@TableName(value = "bpm_form_data", autoResultMap = true)
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class WfFormData extends BaseDO {
+public class BpmFormDataDO extends BaseDO {
 
     /**
      * 编号
@@ -31,7 +31,7 @@ public class WfFormData extends BaseDO {
     /**
      * 表单编号
      *
-     * 关联 {@link WfForm#getId()}
+     * 关联 {@link BpmFormDO#getId()}
      */
     private Long formId;
     /**
@@ -41,7 +41,7 @@ public class WfFormData extends BaseDO {
     /**
      * 表单配置
      *
-     * 冗余 {@link WfForm#getFields()}
+     * 冗余 {@link BpmFormDO#getFields()}
      * 主要考虑,表单是可以修改的
      */
     @TableField(typeHandler = JacksonTypeHandler.class)

+ 2 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/dataobject/oa/OaLeaveDO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/leave/OALeaveDO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa;
+package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave;
 
 import lombok.*;
 import java.util.*;
@@ -17,7 +17,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class OaLeaveDO extends BaseDO {
+public class OALeaveDO extends BaseDO {
 
     /**
      * 请假表单主键

+ 4 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/leave/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * TODO 芋艿:实现请假流程,接入工作流
+ */
+package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave;

+ 4 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * TODO 芋艿:工作流创建后的定义
+ */
+package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task;

+ 18 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/definition/BpmProcessDefinitionMapper.java

@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionDO;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.Collection;
+import java.util.List;
+
+@Mapper
+public interface BpmProcessDefinitionMapper extends BaseMapper<BpmProcessDefinitionDO> {
+
+    default List<BpmProcessDefinitionDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
+        return selectList(new QueryWrapper<BpmProcessDefinitionDO>().in("process_definition_id", processDefinitionIds));
+    }
+
+}

+ 25 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/form/BpmFormMapper.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.form;
+
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 动态表单 Mapper
+ *
+ * @author 风里雾里
+ */
+@Mapper
+public interface BpmFormMapper extends BaseMapperX<BpmFormDO> {
+
+    default PageResult<BpmFormDO> selectPage(BpmFormPageReqVO reqVO) {
+        return selectPage(reqVO, new QueryWrapperX<BpmFormDO>()
+                .likeIfPresent("name", reqVO.getName())
+                .orderByDesc("id"));
+    }
+
+}

+ 9 - 8
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/mysql/oa/OaLeaveMapper.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/oa/OALeaveMapper.java

@@ -1,13 +1,14 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa;
+package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.oa;
 
 import java.util.*;
 
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.OALeaveExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.OALeavePageReqVO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
 import org.apache.ibatis.annotations.Mapper;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
 
 /**
  * 请假申请 Mapper
@@ -15,10 +16,10 @@ import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
  * @author 芋艿
  */
 @Mapper
-public interface OaLeaveMapper extends BaseMapperX<OaLeaveDO> {
+public interface OALeaveMapper extends BaseMapperX<OALeaveDO> {
 
-    default PageResult<OaLeaveDO> selectPage(OaLeavePageReqVO reqVO) {
-        return selectPage(reqVO, new QueryWrapperX<OaLeaveDO>()
+    default PageResult<OALeaveDO> selectPage(OALeavePageReqVO reqVO) {
+        return selectPage(reqVO, new QueryWrapperX<OALeaveDO>()
                 .eqIfPresent("process_instance_id", reqVO.getProcessInstanceId())
                 .eqIfPresent("status", reqVO.getStatus())
                 .eqIfPresent("user_id", reqVO.getUserId())
@@ -30,8 +31,8 @@ public interface OaLeaveMapper extends BaseMapperX<OaLeaveDO> {
                 .orderByDesc("id")        );
     }
 
-    default List<OaLeaveDO> selectList(OaLeaveExportReqVO reqVO) {
-        return selectList(new QueryWrapperX<OaLeaveDO>()
+    default List<OALeaveDO> selectList(OALeaveExportReqVO reqVO) {
+        return selectList(new QueryWrapperX<OALeaveDO>()
                 .eqIfPresent("process_instance_id", reqVO.getProcessInstanceId())
                 .eqIfPresent("status", reqVO.getStatus())
                 .eqIfPresent("user_id", reqVO.getUserId())

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

@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.enums;
+
+import cn.iocoder.yudao.framework.common.exception.ErrorCode;
+
+/**
+ * 工作流 错误码枚举类
+ *
+ * 工作流系统,使用 1-009-000-000 段
+ */
+public interface BpmErrorCodeConstants {
+
+    // ==========  通用流程处理 模块 1-009-000-000 ==========
+    ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009000001, "流程实例不存在");
+    ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常");
+
+    // ========== OA 流程模块 1-009-001-000 ==========
+    ErrorCode OA_LEAVE_NOT_EXISTS = new ErrorCode(1009001001, "请假申请不存在");
+    ErrorCode OA_PM_POST_NOT_EXISTS = new ErrorCode(1009001002, "项目经理岗位未设置");
+    ErrorCode OA_DEPART_PM_POST_NOT_EXISTS = new ErrorCode(1009001009, "部门的项目经理不存在");
+    ErrorCode OA_BM_POST_NOT_EXISTS = new ErrorCode(1009001004, "部门经理岗位未设置");
+    ErrorCode OA_DEPART_BM_POST_NOT_EXISTS = new ErrorCode(1009001005, "部门的部门经理不存在");
+    ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1009001006, "HR岗位未设置");
+    ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1009001007, "请假天数必须>=1");
+
+    // ========== 流程模型 1-009-002-000 ==========
+    ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程");
+    ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在");
+    ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
+
+    // ========== 流程定义 1-009-003-000 ==========
+    ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
+    ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图");
+    ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在");
+    ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003002, "流程定义处于挂起状态");
+
+    // ========== 流程实例 1-009-004-000 ==========
+
+
+    // ========== 动态表单模块 1-009-010-000 ==========
+    ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");
+    ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009010000, "表单项({}) 和 ({}) 使用了相同的字段名({})");
+
+}

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

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 流程状态
+ */
+@Getter
+@AllArgsConstructor
+public enum FlowStatusEnum {
+
+    HANDLE(1, "处理中"),
+
+    PASS(2, "审批通过"),
+
+    REJECTED(3, "审批不通过");
+
+    /**
+     * 状态
+     */
+    private final Integer status;
+
+
+    /**
+     * 描述
+     */
+    private final String desc;
+}

+ 9 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/package-info.java

@@ -0,0 +1,9 @@
+/**
+ * bpm 包下,业务流程管理(Business Process Management),我们放工作流的功能,基于 activiti 7 版本实现。
+ * 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等
+ *
+ * bpm 解释:https://baike.baidu.com/item/BPM/1933
+ *
+ * 缩写:bpm
+ */
+package cn.iocoder.yudao.adminserver.modules.bpm;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupManagerService.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/config/UserGroupManagerService.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.config;
+package cn.iocoder.yudao.adminserver.modules.bpm.service.config;
 
 
 import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysPostService;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupsProvider.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/config/UserGroupsProvider.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.config;
+package cn.iocoder.yudao.adminserver.modules.bpm.service.config;
 
 import cn.iocoder.yudao.framework.security.core.LoginUser;
 import org.activiti.api.runtime.shared.security.PrincipalGroupsProvider;

+ 115 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmProcessDefinitionService.java

@@ -0,0 +1,115 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import org.activiti.bpmn.model.BpmnModel;
+import org.activiti.engine.repository.Deployment;
+import org.activiti.engine.repository.ProcessDefinition;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 流程定义接口
+ *
+ * @author yunlong.li
+ * @author ZJQ
+ */
+public interface BpmProcessDefinitionService {
+
+    /**
+     * 获得流程定义分页
+     *
+     * @param pageReqVO 分页入参
+     * @return 流程定义 Page
+     */
+    PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);
+
+    /**
+     * 获得流程定义对应的 BPMN XML
+     *
+     * @param id 流程定义编号
+     * @return BPMN XML
+     */
+    String getProcessDefinitionBpmnXML(String id);
+
+    /**
+     * 获得 Bpmn 模型
+     *
+     * @param processDefinitionId 流程定义的编号
+     * @return Bpmn 模型
+     */
+    BpmnModel getBpmnModel(String processDefinitionId);
+
+    /**
+     * 获得编号对应的 ProcessDefinition
+     *
+     * @param id 编号
+     * @return 流程定义
+     */
+    ProcessDefinition getProcessDefinition(String id);
+
+    /**
+     * 获得 id 对应的 Deployment
+     *
+     * @param id 部署编号
+     * @return 流程部署
+     */
+    Deployment getDeployment(String id);
+
+    /**
+     * 获得 ids 对应的 Deployment 数组
+     *
+     * @param ids 部署编号的数组
+     * @return 流程部署的数组
+     */
+    List<Deployment> getDeployments(Set<String> ids);
+
+    /**
+     * 获得 ids 对应的 Deployment Map
+     *
+     * @param ids 部署编号的数组
+     * @return 流程部署 Map
+     */
+    default Map<String, Deployment> getDeploymentMap(Set<String> ids) {
+        return CollectionUtils.convertMap(getDeployments(ids), Deployment::getId);
+    }
+
+    /**
+     * 获得 deploymentId 对应的 ProcessDefinition
+     *
+     * @param deploymentId 部署编号
+     * @return 流程定义
+     */
+    ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId);
+
+    /**
+     * 获得 deploymentIds 对应的 ProcessDefinition 数组
+     *
+     * @param deploymentIds 部署编号的数组
+     * @return 流程定义的数组
+     */
+    List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds);
+
+    /**
+     * 创建流程定义
+     *
+     * @param createReqDTO 创建信息
+     * @return 流程编号
+     */
+    String createProcessDefinition(@Valid BpmDefinitionCreateReqDTO createReqDTO);
+
+    /**
+     * 更新流程定义的挂起状态
+     *
+     * @param id 流程定义的编号
+     * @param state 挂起状态 {@link org.activiti.engine.impl.persistence.entity.SuspensionState}
+     */
+    void updateProcessDefinitionState(String id, Integer state);
+
+}

+ 43 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmDefinitionCreateReqDTO.java

@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * 流程定义创建 Request DTO
+ */
+@Data
+public class BpmDefinitionCreateReqDTO {
+
+    /**
+     * 流程标识
+     */
+    @NotEmpty(message = "流程标识不能为空")
+    private String key;
+    /**
+     * 流程名称
+     */
+    @NotEmpty(message = "流程名称不能为空")
+    private String name;
+    /**
+     * 流程描述
+     */
+    private String description;
+    /**
+     * 流程分类
+     * 参见 bpm_model_category 数据字典
+     */
+    @NotEmpty(message = "流程分类不能为空")
+    private String category;
+    /**
+     * BPMN XML
+     */
+    @NotEmpty(message = "BPMN XML 不能为空")
+    private String bpmnXml;
+    /**
+     * 动态表单编号,允许空
+     */
+    private Long formId;
+
+}

+ 193 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java

@@ -0,0 +1,193 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageItemRespVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.BpmProcessDefinitionPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmDefinitionConvert;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmProcessDefinitionMapper;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.object.PageUtils;
+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.impl.persistence.entity.SuspensionState;
+import org.activiti.engine.repository.Deployment;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.repository.ProcessDefinitionQuery;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;
+import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+
+/**
+ * 流程定义实现
+ * 主要进行 Activiti {@link ProcessDefinition} 和 {@link Deployment} 的维护
+ *
+ * @author yunlongn
+ * @author ZJQ
+ */
+@Service
+@Validated
+@Slf4j
+public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {
+
+    private static final String BPMN_FILE_SUFFIX = ".bpmn";
+
+    private static final BpmnXMLConverter BPMN_XML_CONVERTER = new BpmnXMLConverter();
+
+    @Resource
+    private RepositoryService repositoryService;
+    @Resource
+    private BpmFormService bpmFormService;
+
+    @Resource
+    private BpmProcessDefinitionMapper processDefinitionMapper;
+
+    @Override
+    public PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
+        ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
+        if (StrUtil.isNotBlank(pageVO.getKey())) {
+            definitionQuery.processDefinitionKey(pageVO.getKey());
+        }
+        // 执行查询
+        List<ProcessDefinition> processDefinitions = definitionQuery.orderByProcessDefinitionId().desc()
+                .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
+        if (CollUtil.isEmpty(processDefinitions)) {
+            return new PageResult<>(Collections.emptyList(), definitionQuery.count());
+        }
+
+        // 获得 Deployment Map
+        Set<String> deploymentIds = new HashSet<>();
+        processDefinitions.forEach(definition -> CollectionUtils.addIfNotNull(deploymentIds, definition.getDeploymentId()));
+        Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds);
+
+        // 获得 BpmProcessDefinitionDO Map
+        List<BpmProcessDefinitionDO> processDefinitionDOs = Collections.emptyList();
+        processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
+                convertList(processDefinitions, ProcessDefinition::getId));
+        Map<String, BpmProcessDefinitionDO> processDefinitionDOMap = CollectionUtils.convertMap(processDefinitionDOs,
+                BpmProcessDefinitionDO::getProcessDefinitionId);
+
+        // 获得 Form Map
+        Set<Long> formIds = CollectionUtils.convertSet(processDefinitionDOs, BpmProcessDefinitionDO::getFormId);
+        Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds);
+
+        // 拼接结果
+        long definitionCount = definitionQuery.count();
+        return new PageResult<>(BpmDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap,
+                processDefinitionDOMap, formMap), definitionCount);
+    }
+
+    @Override
+    public String getProcessDefinitionBpmnXML(String id) {
+        BpmnModel bpmnModel = repositoryService.getBpmnModel(id);
+        if (bpmnModel == null) {
+            return null;
+        }
+        byte[] bpmnBytes = BPMN_XML_CONVERTER.convertToXML(bpmnModel);
+        return StrUtil.utf8Str(bpmnBytes);
+    }
+
+    @Override
+    public BpmnModel getBpmnModel(String processDefinitionId) {
+        return repositoryService.getBpmnModel(processDefinitionId);
+    }
+
+    @Override
+    public ProcessDefinition getProcessDefinition(String id) {
+        return repositoryService.getProcessDefinition(id);
+    }
+
+    @Override
+    public Deployment getDeployment(String id) {
+        if (StrUtil.isEmpty(id)) {
+            return null;
+        }
+        return repositoryService.createDeploymentQuery().deploymentId(id).singleResult();
+    }
+
+    @Override
+    public List<Deployment> getDeployments(Set<String> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return Collections.emptyList();
+        }
+        List<Deployment> list = new ArrayList<>(ids.size());
+        for (String id : ids) {
+            CollectionUtils.addIfNotNull(list, getDeployment(id));
+        }
+        return list;
+    }
+
+    @Override
+    public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) {
+        return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
+    }
+
+    @Override
+    public List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds) {
+        if (CollUtil.isEmpty(deploymentIds)) {
+            return Collections.emptyList();
+        }
+        return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
+    public String createProcessDefinition(BpmDefinitionCreateReqDTO createReqDTO) {
+        // 创建 Deployment 部署
+        Deployment deploy = repositoryService.createDeployment()
+                .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
+                .addString(createReqDTO.getName() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnXml())
+                .deploy();
+
+        // 设置 ProcessDefinition 的 category 分类
+        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();
+        repositoryService.setProcessDefinitionCategory(definition.getId(), createReqDTO.getCategory());
+        // 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 <bpmn2:process /> 的 id 和 name 决定
+        // 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。
+        //          否则,会导致 ProcessDefinition 的分页无法查询到。
+        if (!Objects.equals(definition.getKey(), createReqDTO.getKey())) {
+            throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, createReqDTO.getKey(), definition.getKey());
+        }
+        if (!Objects.equals(definition.getName(), createReqDTO.getName())) {
+            throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, createReqDTO.getName(), definition.getName());
+        }
+
+        // 插入拓展表
+        BpmProcessDefinitionDO definitionDO = BpmDefinitionConvert.INSTANCE.convert2(createReqDTO)
+                .setProcessDefinitionId(definition.getId());
+        processDefinitionMapper.insert(definitionDO);
+        return definition.getId();
+    }
+
+    @Override
+    public void updateProcessDefinitionState(String id, Integer state) {
+        // 激活
+        if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {
+            repositoryService.activateProcessDefinitionById(id, true, null);
+            return;
+        }
+        // 挂起
+        if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {
+            repositoryService.suspendProcessDefinitionById(id, true, null);
+            return;
+        }
+        log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);
+    }
+
+}

+ 92 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/BpmFormService.java

@@ -0,0 +1,92 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.form;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import org.activiti.engine.repository.Model;
+
+import javax.validation.Valid;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 动态表单 Service 接口
+ *
+ * @author  @风里雾里
+ */
+public interface BpmFormService {
+
+    /**
+     * 创建动态表单
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createForm(@Valid BpmFormCreateReqVO createReqVO);
+
+    /**
+     * 更新动态表单
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateForm(@Valid BpmFormUpdateReqVO updateReqVO);
+
+    /**
+     * 删除动态表单
+     *
+     * @param id 编号
+     */
+    void deleteForm(Long id);
+
+    /**
+     * 获得动态表单
+     *
+     * @param id 编号
+     * @return 动态表单
+     */
+    BpmFormDO getForm(Long id);
+
+    /**
+     * 获得动态表单列表
+     *
+     * @return 动态表单列表
+     */
+    List<BpmFormDO> getFormList();
+
+    /**
+     * 获得动态表单列表
+     *
+     * @param ids 编号
+     * @return 动态表单列表
+     */
+    List<BpmFormDO> getFormList(Collection<Long> ids);
+
+    /**
+     * 获得动态表单 Map
+     *
+     * @param ids 编号
+     * @return 动态表单 Map
+     */
+    default Map<Long, BpmFormDO> getFormMap(Collection<Long> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return Collections.emptyMap();
+        }
+        return CollectionUtils.convertMap(this.getFormList(ids), BpmFormDO::getId);
+    }
+
+    /**
+     * 获得动态表单分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 动态表单分页
+     */
+    PageResult<BpmFormDO> getFormPage(BpmFormPageReqVO pageReqVO);
+
+}

+ 25 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/dto/BpmFormFieldRespDTO.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.form.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * Bpm 表单的 Field 表单项 Response DTO
+ * 字段的定义,可见 https://github.com/JakHuang/form-generator/issues/46 文档
+ *
+ * @author 芋道源码
+ */
+@Data
+public class BpmFormFieldRespDTO {
+
+    /**
+     * 表单标题
+     */
+    private String label;
+    /**
+     * 表单字段的属性名,可自定义
+     */
+    @JsonProperty(value = "vModel")
+    private String vModel;
+
+}

+ 113 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/impl/BpmFormServiceImpl.java

@@ -0,0 +1,113 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.form.impl;
+
+import cn.hutool.core.lang.Assert;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.convert.form.BpmFormConvert;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.form.BpmFormMapper;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.form.dto.BpmFormFieldRespDTO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.FORM_FIELD_REPEAT;
+import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.FORM_NOT_EXISTS;
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+
+/**
+ * 动态表单 Service 实现类
+ *
+ * @author 风里雾里
+ */
+@Service
+@Validated
+public class BpmFormServiceImpl implements BpmFormService {
+
+    @Resource
+    private BpmFormMapper formMapper;
+
+    @Override
+    public Long createForm(BpmFormCreateReqVO createReqVO) {
+        this.checkFields(createReqVO.getFields());
+        // 插入
+        BpmFormDO form = BpmFormConvert.INSTANCE.convert(createReqVO);
+        formMapper.insert(form);
+        // 返回
+        return form.getId();
+    }
+
+    @Override
+    public void updateForm(BpmFormUpdateReqVO updateReqVO) {
+        this.checkFields(updateReqVO.getFields());
+        // 校验存在
+        this.validateFormExists(updateReqVO.getId());
+        // 更新
+        BpmFormDO updateObj = BpmFormConvert.INSTANCE.convert(updateReqVO);
+        formMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteForm(Long id) {
+        // 校验存在
+        this.validateFormExists(id);
+        // 删除
+        formMapper.deleteById(id);
+    }
+
+    private void validateFormExists(Long id) {
+        if (formMapper.selectById(id) == null) {
+            throw exception(FORM_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public BpmFormDO getForm(Long id) {
+        return formMapper.selectById(id);
+    }
+
+    @Override
+    public List<BpmFormDO> getFormList() {
+        return formMapper.selectList();
+    }
+
+    @Override
+    public List<BpmFormDO> getFormList(Collection<Long> ids) {
+        return formMapper.selectBatchIds(ids);
+    }
+
+    @Override
+    public PageResult<BpmFormDO> getFormPage(BpmFormPageReqVO pageReqVO) {
+        return formMapper.selectPage(pageReqVO);
+    }
+
+    /**
+     * 校验 Field,避免 field 重复
+     *
+     * @param fields field 数组
+     */
+    private void checkFields(List<String> fields) {
+        Map<String, String> fieldMap = new HashMap<>(); // key 是 vModel,value 是 label
+        for (String field : fields) {
+            BpmFormFieldRespDTO fieldDTO = JsonUtils.parseObject(field, BpmFormFieldRespDTO.class);
+            Assert.notNull(fieldDTO);
+            String oldLabel = fieldMap.put(fieldDTO.getVModel(), fieldDTO.getLabel());
+            // 如果不存在,则直接返回
+            if (oldLabel == null) {
+                continue;
+            }
+            // 如果存在,则报错
+            throw exception(FORM_FIELD_REPEAT, oldLabel, fieldDTO.getLabel(), fieldDTO.getVModel());
+        }
+    }
+
+}

+ 68 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/model/BpmModelService.java

@@ -0,0 +1,68 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.model;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo.*;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import javax.validation.Valid;
+
+/**
+ * 流程模型接口
+ *
+ * @author yunlongn
+ */
+public interface BpmModelService {
+
+    /**
+     * 获得流程模型分页
+     *
+     * @param pageVO 分页查询
+     * @return 流程模型分页
+     */
+    PageResult<BpmModelPageItemRespVO> getModelPage(ModelPageReqVO pageVO);
+
+    /**
+     * 获得流程模块
+     *
+     * @param id 编号
+     * @return 流程模型
+     */
+    BpmModelRespVO getModel(String id);
+
+    /**
+     * 创建流程模型
+     *
+     * @param modelVO 创建信息
+     * @return 创建的流程模型的编号
+     */
+    String createModel(@Valid BpmModelCreateReqVO modelVO);
+
+    /**
+     * 修改流程模型
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateModel(@Valid BpmModelUpdateReqVO updateReqVO);
+
+    /**
+     * 将流程模型,部署成一个流程定义
+     *
+     * @param id 编号
+     */
+    void deployModel(String id);
+
+    /**
+     * 删除模型
+     *
+     * @param id 编号
+     */
+    void deleteModel(String id);
+
+    /**
+     * 修改模型的状态,实际更新的部署的流程定义的状态
+     *
+     * @param id 编号
+     * @param state 状态 {@link org.activiti.engine.impl.persistence.entity.SuspensionState}
+     */
+    void updateModelState(String id, Integer state);
+
+}

+ 23 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/model/dto/BpmModelMetaInfoRespDTO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.model.dto;
+
+import lombok.Data;
+
+/**
+ * BPM 流程 MetaInfo Response DTO
+ * 主要用于 {@link org.activiti.engine.repository.Model#setMetaInfo(String)} 的存储
+ *
+ * @author 芋道源码
+ */
+@Data
+public class BpmModelMetaInfoRespDTO {
+
+    /**
+     * 流程描述
+     */
+    private String description;
+    /**
+     * 表单编号
+     */
+    private Long formId;
+
+}

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

@@ -0,0 +1,214 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.model.impl;
+
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo.*;
+import cn.iocoder.yudao.adminserver.modules.bpm.convert.model.BpmModelConvert;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.model.BpmModelService;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.model.dto.BpmModelMetaInfoRespDTO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import cn.iocoder.yudao.framework.common.util.object.PageUtils;
+import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.impl.persistence.entity.SuspensionState;
+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.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.ObjectUtils;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
+
+/**
+ * 流程定义实现
+ * 主要进行 Activiti {@link Model} 的维护
+ *
+ * @author yunlongn
+ */
+@Service
+@Validated
+@Slf4j
+public class BpmModelServiceImpl implements BpmModelService {
+
+    @Resource
+    private RepositoryService repositoryService;
+    @Resource
+    private BpmFormService bpmFormService;
+    @Resource
+    private BpmProcessDefinitionService bpmProcessDefinitionService;
+
+    @Override
+    public PageResult<BpmModelPageItemRespVO> getModelPage(ModelPageReqVO pageVO) {
+        ModelQuery modelQuery = repositoryService.createModelQuery();
+        if (StrUtil.isNotBlank(pageVO.getKey())) {
+            modelQuery.modelKey(pageVO.getKey());
+        }
+        if (StrUtil.isNotBlank(pageVO.getName())) {
+            modelQuery.modelNameLike("%" + pageVO.getName() + "%"); // 模糊匹配
+        }
+        if (StrUtil.isNotBlank(pageVO.getCategory())) {
+            modelQuery.modelCategory(pageVO.getCategory());
+        }
+        // 执行查询
+        List<Model> models = modelQuery.orderByCreateTime().desc()
+                .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
+
+        // 获得 Form Map
+        Set<Long> formIds = CollectionUtils.convertSet(models, model -> {
+            BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+            return metaInfo != null ? metaInfo.getFormId() : null;
+        });
+        Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds);
+
+        // 获得 Deployment Map
+        Set<String> deploymentIds = new HashSet<>();
+        models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
+        Map<String, Deployment> deploymentMap = bpmProcessDefinitionService.getDeploymentMap(deploymentIds);
+        // 获得 ProcessDefinition Map
+        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
+        Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
+
+        // 拼接结果
+        long modelCount = modelQuery.count();
+        return new PageResult<>(BpmModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount);
+    }
+
+    @Override
+    public BpmModelRespVO getModel(String id) {
+        Model model = repositoryService.getModel(id);
+        if (model == null) {
+            return null;
+        }
+        BpmModelRespVO modelRespVO = BpmModelConvert.INSTANCE.convert(model);
+        // 拼接 bpmn XML
+        byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
+        modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes));
+        return modelRespVO;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
+    public String createModel(BpmModelCreateReqVO createReqVO) {
+        checkKeyNCName(createReqVO.getKey());
+        // 校验流程标识已经存在
+        Model keyModel = this.getModelByKey(createReqVO.getKey());
+        if (keyModel != null) {
+            throw exception(MODEL_KEY_EXISTS, createReqVO.getKey());
+        }
+
+        // 创建流程定义
+        Model model = repositoryService.newModel();
+        BpmModelConvert.INSTANCE.copy(model, createReqVO);
+        // 保存流程定义
+        repositoryService.saveModel(model);
+        // 添加 BPMN XML
+        repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(createReqVO.getBpmnXml()));
+        return model.getId();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
+    public void updateModel(BpmModelUpdateReqVO updateReqVO) {
+        checkKeyNCName(updateReqVO.getKey());
+        // 校验流程模型存在
+        Model model = repositoryService.getModel(updateReqVO.getId());
+        if (model == null) {
+            throw exception(MODEL_NOT_EXISTS);
+        }
+
+        // 修改流程定义
+        BpmModelConvert.INSTANCE.copy(model, updateReqVO);
+        // 更新模型
+        repositoryService.saveModel(model);
+        // 更新 BPMN XML
+        repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(updateReqVO.getBpmnXml()));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
+    public void deployModel(String id) {
+        // 校验流程模型存在
+        Model model = repositoryService.getModel(id);
+        if (ObjectUtils.isEmpty(model)) {
+            throw exception(MODEL_NOT_EXISTS);
+        }
+        byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId());
+        if (bpmnBytes == null) {
+            throw exception(MODEL_NOT_EXISTS);
+        }
+
+        // 创建流程定义
+        BpmDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model)
+                .setBpmnXml(StrUtil.utf8Str(bpmnBytes));
+        String definitionId = bpmProcessDefinitionService.createProcessDefinition(definitionCreateReqDTO);
+
+        // 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。
+        if (StrUtil.isNotEmpty(model.getDeploymentId())) {
+            ProcessDefinition oldDefinition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
+            if (oldDefinition != null) {
+                bpmProcessDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
+            }
+        }
+
+        // 更新 model 的 deploymentId,进行关联
+        ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinition(definitionId);
+        model.setDeploymentId(definition.getDeploymentId());
+        repositoryService.saveModel(model);
+    }
+
+    @Override
+    public void deleteModel(String id) {
+        // 校验流程模型存在
+        Model model = repositoryService.getModel(id);
+        if (model == null) {
+            throw exception(MODEL_NOT_EXISTS);
+        }
+        // 执行删除
+        repositoryService.deleteModel(id);
+    }
+
+    @Override
+    public void updateModelState(String id, Integer state) {
+        // 校验流程模型存在
+        Model model = repositoryService.getModel(id);
+        if (model == null) {
+            throw exception(MODEL_NOT_EXISTS);
+        }
+        // 校验流程定义存在
+        ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
+        if (definition == null) {
+            throw exception(PROCESS_DEFINITION_NOT_EXISTS);
+        }
+
+        // 更新状态
+        bpmProcessDefinitionService.updateProcessDefinitionState(definition.getId(), state);
+    }
+
+    private Model getModelByKey(String key) {
+        return repositoryService.createModelQuery().modelKey(key).singleResult();
+    }
+
+    private void checkKeyNCName(String key) {
+        if (!ValidationUtils.isXmlNCName(key)) {
+            throw exception(MODEL_KEY_VALID);
+        }
+    }
+
+}

+ 40 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/LeaveApplyEndProcessor.java

@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.oa;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.oa.OALeaveMapper;
+import cn.iocoder.yudao.adminserver.modules.bpm.enums.FlowStatusEnum;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.ExecutionListener;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.Objects;
+
+
+/**
+ * 请假流程结束流程监听处理服务, 根据请假申请审批通过,还是未通过, 更新请假表单
+ */
+@Component
+public class LeaveApplyEndProcessor implements ExecutionListener {
+
+    @Resource
+    private OALeaveMapper leaveMapper;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void notify(DelegateExecution delegateExecution) {
+        final String businessKey = delegateExecution.getProcessInstanceBusinessKey();
+        final Object approved = delegateExecution.getVariable("approved");
+        OALeaveDO updateDo = new OALeaveDO();
+        updateDo.setId(Long.valueOf(businessKey));
+        if (Objects.equals(approved, true)) {
+            updateDo.setStatus(FlowStatusEnum.PASS.getStatus());
+        } else {
+            updateDo.setStatus(FlowStatusEnum.REJECTED.getStatus());
+        }
+
+        leaveMapper.updateById(updateDo);
+    }
+
+}

+ 17 - 13
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/OaLeaveService.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/OALeaveService.java

@@ -1,11 +1,8 @@
-package cn.iocoder.yudao.adminserver.modules.activiti.service.oa;
+package cn.iocoder.yudao.adminserver.modules.bpm.service.oa;
 
 
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveCreateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveExportReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeavePageReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveUpdateReqVO;
-import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.*;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
 import javax.validation.Valid;
@@ -17,7 +14,7 @@ import java.util.List;
  *
  * @author 芋艿
  */
-public interface OaLeaveService {
+public interface OALeaveService {
 
     /**
      * 创建请假申请
@@ -25,14 +22,14 @@ public interface OaLeaveService {
      * @param createReqVO 创建信息
      * @return 编号
      */
-    Long createLeave(@Valid OaLeaveCreateReqVO createReqVO);
+    Long createLeave(@Valid OALeaveCreateReqVO createReqVO);
 
     /**
      * 更新请假申请
      *
      * @param updateReqVO 更新信息
      */
-    void updateLeave(@Valid OaLeaveUpdateReqVO updateReqVO);
+    void updateLeave(@Valid OALeaveUpdateReqVO updateReqVO);
 
     /**
      * 删除请假申请
@@ -47,7 +44,7 @@ public interface OaLeaveService {
      * @param id 编号
      * @return 请假申请
      */
-    OaLeaveDO getLeave(Long id);
+    OALeaveDO getLeave(Long id);
 
     /**
      * 获得请假申请列表
@@ -55,7 +52,7 @@ public interface OaLeaveService {
      * @param ids 编号
      * @return 请假申请列表
      */
-    List<OaLeaveDO> getLeaveList(Collection<Long> ids);
+    List<OALeaveDO> getLeaveList(Collection<Long> ids);
 
     /**
      * 获得请假申请分页
@@ -63,7 +60,7 @@ public interface OaLeaveService {
      * @param pageReqVO 分页查询
      * @return 请假申请分页
      */
-    PageResult<OaLeaveDO> getLeavePage(OaLeavePageReqVO pageReqVO);
+    PageResult<OALeaveDO> getLeavePage(OALeavePageReqVO pageReqVO);
 
     /**
      * 获得请假申请列表, 用于 Excel 导出
@@ -71,6 +68,13 @@ public interface OaLeaveService {
      * @param exportReqVO 查询条件
      * @return 请假申请列表
      */
-    List<OaLeaveDO> getLeaveList(OaLeaveExportReqVO exportReqVO);
+    List<OALeaveDO> getLeaveList(OALeaveExportReqVO exportReqVO);
 
+
+
+    /**
+     * 获取本人请假申请流程中审批人员
+     * @return  包括,本人部门的项目经理, 部门经理,  HR
+     */
+    OALeaveApplyMembersVO getLeaveApplyMembers();
 }

Vissa filer visades inte eftersom för många filer har ändrats