Commit db3c713122a71e992460cf8345ceee116d7e188c
1 parent
aac6cc7b
1. 修改流程的表单定义,支持业务表单。
2. 流程提交时,记录表单值
Showing
15 changed files
with
190 additions
and
107 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/BpmProcessDefinitionController.java
| ... | ... | @@ -32,6 +32,8 @@ public class BpmProcessDefinitionController { |
| 32 | 32 | @Resource |
| 33 | 33 | private BpmProcessDefinitionService bpmDefinitionService; |
| 34 | 34 | |
| 35 | + // TODO 芋艿:权限相关 | |
| 36 | + | |
| 35 | 37 | @GetMapping ("/page") |
| 36 | 38 | @ApiOperation(value = "获得流程定义分页") |
| 37 | 39 | @PreAuthorize("@ss.hasPermission('bpm:model:query')") // 暂时使用 model 的权限标识 | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/form/BpmFormRespVO.java
| ... | ... | @@ -18,6 +18,7 @@ public class BpmFormRespVO extends BpmFormBaseVO { |
| 18 | 18 | |
| 19 | 19 | @ApiModelProperty(value = "表单编号", required = true, example = "1024") |
| 20 | 20 | private Long id; |
| 21 | + | |
| 21 | 22 | @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串") |
| 22 | 23 | @NotNull(message = "表单的配置不能为空") |
| 23 | 24 | private String conf; | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/definition/vo/process/BpmProcessDefinitionRespVO.java
| ... | ... | @@ -5,6 +5,8 @@ import io.swagger.annotations.ApiModelProperty; |
| 5 | 5 | import lombok.Data; |
| 6 | 6 | |
| 7 | 7 | import javax.validation.constraints.NotEmpty; |
| 8 | +import javax.validation.constraints.NotNull; | |
| 9 | +import java.util.List; | |
| 8 | 10 | |
| 9 | 11 | @ApiModel("流程定义 Response VO") |
| 10 | 12 | @Data |
| ... | ... | @@ -27,8 +29,22 @@ public class BpmProcessDefinitionRespVO { |
| 27 | 29 | @NotEmpty(message = "流程分类不能为空") |
| 28 | 30 | private String category; |
| 29 | 31 | |
| 30 | - @ApiModelProperty(value = "表单编号", example = "1024") | |
| 32 | + @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") | |
| 33 | + private Integer formType; | |
| 34 | + @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 31 | 35 | private Long formId; |
| 36 | + @ApiModelProperty(value = "表单的配置", required = true, | |
| 37 | + notes = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 38 | + private String formConf; | |
| 39 | + @ApiModelProperty(value = "表单项的数组", required = true, | |
| 40 | + notes = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 41 | + private List<String> formFields; | |
| 42 | + @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", | |
| 43 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 44 | + private String formCustomCreatePath; | |
| 45 | + @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", | |
| 46 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 47 | + private String formCustomViewPath; | |
| 32 | 48 | |
| 33 | 49 | @ApiModelProperty(value = "中断状态", required = true, example = "1", notes = "参见 SuspensionState 枚举") |
| 34 | 50 | private Integer suspensionState; | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmModelConvert.java
| ... | ... | @@ -83,7 +83,7 @@ public interface BpmModelConvert { |
| 83 | 83 | |
| 84 | 84 | void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to); |
| 85 | 85 | |
| 86 | - default BpmDefinitionCreateReqDTO convert2(Model model) { | |
| 86 | + default BpmDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) { | |
| 87 | 87 | BpmDefinitionCreateReqDTO createReqDTO = new BpmDefinitionCreateReqDTO(); |
| 88 | 88 | createReqDTO.setModelId(model.getId()); |
| 89 | 89 | createReqDTO.setName(model.getName()); |
| ... | ... | @@ -92,6 +92,11 @@ public interface BpmModelConvert { |
| 92 | 92 | BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); |
| 93 | 93 | // metaInfo |
| 94 | 94 | copyTo(metaInfo, createReqDTO); |
| 95 | + // form | |
| 96 | + if (form != null) { | |
| 97 | + createReqDTO.setFormConf(form.getConf()); | |
| 98 | + createReqDTO.setFormFields(form.getFields()); | |
| 99 | + } | |
| 95 | 100 | return createReqDTO; |
| 96 | 101 | } |
| 97 | 102 | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmProcessDefinitionConvert.java
| ... | ... | @@ -11,6 +11,7 @@ import org.activiti.engine.repository.Deployment; |
| 11 | 11 | import org.activiti.engine.repository.ProcessDefinition; |
| 12 | 12 | import org.mapstruct.Mapper; |
| 13 | 13 | import org.mapstruct.Mapping; |
| 14 | +import org.mapstruct.MappingTarget; | |
| 14 | 15 | import org.mapstruct.Named; |
| 15 | 16 | import org.mapstruct.factory.Mappers; |
| 16 | 17 | |
| ... | ... | @@ -38,19 +39,17 @@ public interface BpmProcessDefinitionConvert { |
| 38 | 39 | } |
| 39 | 40 | |
| 40 | 41 | default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment, |
| 41 | - BpmProcessDefinitionExtDO processDefinitionDO, BpmFormDO form) { | |
| 42 | + BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) { | |
| 42 | 43 | BpmProcessDefinitionPageItemRespVO respVO = convert(bean); |
| 43 | 44 | respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode()); |
| 44 | 45 | if (deployment != null) { |
| 45 | 46 | respVO.setDeploymentTime(deployment.getDeploymentTime()); |
| 46 | 47 | } |
| 47 | 48 | if (form != null) { |
| 48 | - respVO.setFormId(form.getId()); | |
| 49 | 49 | respVO.setFormName(form.getName()); |
| 50 | 50 | } |
| 51 | - if (processDefinitionDO != null) { | |
| 52 | - respVO.setDescription(processDefinitionDO.getDescription()); | |
| 53 | - } | |
| 51 | + // 复制通用属性 | |
| 52 | + copyTo(processDefinitionExtDO, respVO); | |
| 54 | 53 | return respVO; |
| 55 | 54 | } |
| 56 | 55 | |
| ... | ... | @@ -63,9 +62,8 @@ public interface BpmProcessDefinitionConvert { |
| 63 | 62 | return CollectionUtils.convertList(list, processDefinition -> { |
| 64 | 63 | BpmProcessDefinitionRespVO respVO = convert3(processDefinition); |
| 65 | 64 | BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId()); |
| 66 | - if (processDefinitionExtDO != null) { | |
| 67 | - respVO.setFormId(processDefinitionExtDO.getFormId()); | |
| 68 | - } | |
| 65 | + // 复制通用属性 | |
| 66 | + copyTo(processDefinitionExtDO, respVO); | |
| 69 | 67 | return respVO; |
| 70 | 68 | }); |
| 71 | 69 | } |
| ... | ... | @@ -79,4 +77,7 @@ public interface BpmProcessDefinitionConvert { |
| 79 | 77 | SuspensionState.ACTIVE.getStateCode(); |
| 80 | 78 | } |
| 81 | 79 | |
| 80 | + @Mapping(source = "from.id", target = "to.id", ignore = true) | |
| 81 | + void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessDefinitionRespVO to); | |
| 82 | + | |
| 82 | 83 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/definition/BpmFormDataDO.java deleted
| 1 | -package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 4 | -import com.baomidou.mybatisplus.annotation.TableField; | |
| 5 | -import com.baomidou.mybatisplus.annotation.TableName; | |
| 6 | -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 7 | -import lombok.*; | |
| 8 | - | |
| 9 | -import java.util.List; | |
| 10 | -import java.util.Map; | |
| 11 | - | |
| 12 | -/** | |
| 13 | - * 工作流的表单结果 | |
| 14 | - * 用户每次填写工作流的申请表单时,会保存一条记录到该表】 | |
| 15 | - * | |
| 16 | - * @author 芋道源码 | |
| 17 | - */ | |
| 18 | -@TableName(value = "bpm_form_data", autoResultMap = true) | |
| 19 | -@Data | |
| 20 | -@EqualsAndHashCode(callSuper = true) | |
| 21 | -@ToString(callSuper = true) | |
| 22 | -@Builder | |
| 23 | -@NoArgsConstructor | |
| 24 | -@AllArgsConstructor | |
| 25 | -public class BpmFormDataDO extends BaseDO { | |
| 26 | - | |
| 27 | - /** | |
| 28 | - * 编号 | |
| 29 | - */ | |
| 30 | - private Long id; | |
| 31 | - /** | |
| 32 | - * 表单编号 | |
| 33 | - * | |
| 34 | - * 关联 {@link BpmFormDO#getId()} | |
| 35 | - */ | |
| 36 | - private Long formId; | |
| 37 | - /** | |
| 38 | - * 状态 | |
| 39 | - */ | |
| 40 | - private Integer status; | |
| 41 | - /** | |
| 42 | - * 表单配置 | |
| 43 | - * | |
| 44 | - * 冗余 {@link BpmFormDO#getFields()} | |
| 45 | - * 主要考虑,表单是可以修改的 | |
| 46 | - */ | |
| 47 | - @TableField(typeHandler = JacksonTypeHandler.class) | |
| 48 | - private List<String> fields; | |
| 49 | - /** | |
| 50 | - * 表单值 | |
| 51 | - */ | |
| 52 | - @TableField(typeHandler = JacksonTypeHandler.class) | |
| 53 | - private Map<String, Object> values; | |
| 54 | - | |
| 55 | -} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum; | |
| 3 | 4 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | +import com.baomidou.mybatisplus.annotation.TableField; | |
| 4 | 6 | import com.baomidou.mybatisplus.annotation.TableId; |
| 5 | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 6 | 9 | import lombok.*; |
| 7 | 10 | import org.activiti.engine.repository.Model; |
| 8 | 11 | import org.activiti.engine.repository.ProcessDefinition; |
| 9 | 12 | |
| 13 | +import java.util.List; | |
| 14 | + | |
| 10 | 15 | /** |
| 11 | 16 | * Bpm 流程定义的拓展表 |
| 12 | 17 | * 主要解决 Activiti {@link ProcessDefinition} 不支持拓展字段,所以新建拓展表 |
| ... | ... | @@ -43,11 +48,45 @@ public class BpmProcessDefinitionExtDO extends BaseDO { |
| 43 | 48 | * 描述 |
| 44 | 49 | */ |
| 45 | 50 | private String description; |
| 51 | + | |
| 52 | + /** | |
| 53 | + * 表单类型 | |
| 54 | + * | |
| 55 | + * 关联 {@link BpmModelFormTypeEnum} | |
| 56 | + */ | |
| 57 | + private Integer formType; | |
| 46 | 58 | /** |
| 47 | - * 表单编号 | |
| 59 | + * 动态表单编号 | |
| 60 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 48 | 61 | * |
| 49 | 62 | * 关联 {@link BpmFormDO#getId()} |
| 50 | 63 | */ |
| 51 | 64 | private Long formId; |
| 65 | + /** | |
| 66 | + * 表单的配置 | |
| 67 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 68 | + * | |
| 69 | + * 冗余 {@link BpmFormDO#getConf()} | |
| 70 | + */ | |
| 71 | + private String formConf; | |
| 72 | + /** | |
| 73 | + * 表单项的数组 | |
| 74 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 75 | + * | |
| 76 | + * 冗余 {@link BpmFormDO#getFields()} ()} | |
| 77 | + */ | |
| 78 | + @TableField(typeHandler = JacksonTypeHandler.class) | |
| 79 | + private List<String> formFields; | |
| 80 | + /** | |
| 81 | + * 自定义表单的提交路径,使用 Vue 的路由地址 | |
| 82 | + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 | |
| 83 | + */ | |
| 84 | + private String formCustomCreatePath; | |
| 85 | + /** | |
| 86 | + * 自定义表单的查看路径,使用 Vue 的路由地址 | |
| 87 | + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 | |
| 88 | + */ | |
| 89 | + private String formCustomViewPath; | |
| 90 | + | |
| 52 | 91 | |
| 53 | 92 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java
| ... | ... | @@ -3,7 +3,9 @@ package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task; |
| 3 | 3 | import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum; |
| 4 | 4 | import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceStatusEnum; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 6 | +import com.baomidou.mybatisplus.annotation.TableField; | |
| 6 | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 7 | 9 | import lombok.Data; |
| 8 | 10 | import lombok.EqualsAndHashCode; |
| 9 | 11 | import lombok.ToString; |
| ... | ... | @@ -12,6 +14,7 @@ import org.activiti.engine.repository.ProcessDefinition; |
| 12 | 14 | import org.activiti.engine.runtime.ProcessInstance; |
| 13 | 15 | |
| 14 | 16 | import java.util.Date; |
| 17 | +import java.util.Map; | |
| 15 | 18 | |
| 16 | 19 | /** |
| 17 | 20 | * Bpm 流程实例的拓展表 |
| ... | ... | @@ -78,4 +81,10 @@ public class BpmProcessInstanceExtDO extends BaseDO { |
| 78 | 81 | */ |
| 79 | 82 | private Date endTime; |
| 80 | 83 | |
| 84 | + /** | |
| 85 | + * 表单值 | |
| 86 | + */ | |
| 87 | + @TableField(typeHandler = JacksonTypeHandler.class) | |
| 88 | + private Map<String, Object> formVariables; | |
| 89 | + | |
| 81 | 90 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmDefinitionCreateReqDTO.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO; | |
| 3 | 6 | import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum; |
| 7 | +import com.baomidou.mybatisplus.annotation.TableField; | |
| 8 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 4 | 9 | import lombok.Data; |
| 5 | 10 | |
| 11 | +import javax.validation.constraints.AssertTrue; | |
| 6 | 12 | import javax.validation.constraints.NotEmpty; |
| 7 | 13 | import javax.validation.constraints.NotNull; |
| 14 | +import java.util.List; | |
| 15 | +import java.util.Objects; | |
| 8 | 16 | |
| 9 | 17 | /** |
| 10 | 18 | * 流程定义创建 Request DTO |
| ... | ... | @@ -58,6 +66,16 @@ public class BpmDefinitionCreateReqDTO { |
| 58 | 66 | */ |
| 59 | 67 | private Long formId; |
| 60 | 68 | /** |
| 69 | + * 表单的配置 | |
| 70 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 71 | + */ | |
| 72 | + private String formConf; | |
| 73 | + /** | |
| 74 | + * 表单项的数组 | |
| 75 | + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 | |
| 76 | + */ | |
| 77 | + private List<String> formFields; | |
| 78 | + /** | |
| 61 | 79 | * 自定义表单的提交路径,使用 Vue 的路由地址 |
| 62 | 80 | * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 |
| 63 | 81 | */ |
| ... | ... | @@ -68,6 +86,22 @@ public class BpmDefinitionCreateReqDTO { |
| 68 | 86 | */ |
| 69 | 87 | private String formCustomViewPath; |
| 70 | 88 | |
| 89 | + @AssertTrue(message = "流程表单信息不全") | |
| 90 | + public boolean isNormalFormTypeValid() { | |
| 91 | + // 如果非业务表单,则直接通过 | |
| 92 | + if (!Objects.equals(formType, BpmModelFormTypeEnum.NORMAL.getType())) { | |
| 93 | + return true; | |
| 94 | + } | |
| 95 | + return formId != null && StrUtil.isNotEmpty(formConf) && CollUtil.isNotEmpty(formFields); | |
| 96 | + } | |
| 71 | 97 | |
| 98 | + @AssertTrue(message = "业务表单信息不全") | |
| 99 | + public boolean isNormalCustomTypeValid() { | |
| 100 | + // 如果非业务表单,则直接通过 | |
| 101 | + if (!Objects.equals(formType, BpmModelFormTypeEnum.CUSTOM.getType())) { | |
| 102 | + return true; | |
| 103 | + } | |
| 104 | + return StrUtil.isNotEmpty(formCustomCreatePath) && StrUtil.isNotEmpty(formCustomViewPath); | |
| 105 | + } | |
| 72 | 106 | |
| 73 | 107 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmModelServiceImpl.java
| ... | ... | @@ -7,6 +7,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.* |
| 7 | 7 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO; |
| 8 | 8 | import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmModelConvert; |
| 9 | 9 | import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO; |
| 10 | +import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum; | |
| 10 | 11 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; |
| 11 | 12 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService; |
| 12 | 13 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; |
| ... | ... | @@ -36,10 +37,7 @@ import org.springframework.util.ObjectUtils; |
| 36 | 37 | import org.springframework.validation.annotation.Validated; |
| 37 | 38 | |
| 38 | 39 | import javax.annotation.Resource; |
| 39 | -import java.util.HashSet; | |
| 40 | -import java.util.List; | |
| 41 | -import java.util.Map; | |
| 42 | -import java.util.Set; | |
| 40 | +import java.util.*; | |
| 43 | 41 | import java.util.function.Consumer; |
| 44 | 42 | |
| 45 | 43 | import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; |
| ... | ... | @@ -177,15 +175,13 @@ public class BpmModelServiceImpl implements BpmModelService { |
| 177 | 175 | } |
| 178 | 176 | // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素; |
| 179 | 177 | // 校验表单已配 |
| 180 | - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); | |
| 181 | - if (metaInfo == null || metaInfo.getFormType() == null) { | |
| 182 | - throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); | |
| 183 | - } | |
| 178 | + // 校验表单存在 | |
| 179 | + BpmFormDO form = checkFormConfig(model); | |
| 184 | 180 | // 校验任务分配规则已配置 |
| 185 | 181 | checkTaskAssignRuleAllConfig(id); |
| 186 | 182 | |
| 187 | 183 | // 创建流程定义 |
| 188 | - BpmDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model) | |
| 184 | + BpmDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form) | |
| 189 | 185 | .setBpmnXml(StrUtil.utf8Str(bpmnBytes)); |
| 190 | 186 | String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO); |
| 191 | 187 | |
| ... | ... | @@ -221,6 +217,28 @@ public class BpmModelServiceImpl implements BpmModelService { |
| 221 | 217 | }); |
| 222 | 218 | } |
| 223 | 219 | |
| 220 | + /** | |
| 221 | + * 校验流程表单已配置 | |
| 222 | + * | |
| 223 | + * @param model 流程模型 | |
| 224 | + * @return 流程表单 | |
| 225 | + */ | |
| 226 | + private BpmFormDO checkFormConfig(Model model) { | |
| 227 | + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); | |
| 228 | + if (metaInfo == null || metaInfo.getFormType() == null) { | |
| 229 | + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); | |
| 230 | + } | |
| 231 | + // 校验表单存在 | |
| 232 | + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) { | |
| 233 | + BpmFormDO form = formService.getForm(metaInfo.getFormId()); | |
| 234 | + if (form == null) { | |
| 235 | + throw exception(FORM_NOT_EXISTS); | |
| 236 | + } | |
| 237 | + return form; | |
| 238 | + } | |
| 239 | + return null; | |
| 240 | + } | |
| 241 | + | |
| 224 | 242 | @Override |
| 225 | 243 | @Transactional(rollbackFor = Exception.class) |
| 226 | 244 | public void deleteModel(String id) { | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java
| ... | ... | @@ -34,7 +34,8 @@ import java.util.*; |
| 34 | 34 | import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH; |
| 35 | 35 | import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH; |
| 36 | 36 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 37 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 37 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | |
| 38 | +import static java.util.Collections.emptyList; | |
| 38 | 39 | |
| 39 | 40 | /** |
| 40 | 41 | * 流程定义实现 |
| ... | ... | @@ -70,22 +71,22 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ |
| 70 | 71 | List<ProcessDefinition> processDefinitions = definitionQuery.orderByProcessDefinitionVersion().desc() |
| 71 | 72 | .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); |
| 72 | 73 | if (CollUtil.isEmpty(processDefinitions)) { |
| 73 | - return new PageResult<>(Collections.emptyList(), definitionQuery.count()); | |
| 74 | + return new PageResult<>(emptyList(), definitionQuery.count()); | |
| 74 | 75 | } |
| 75 | 76 | |
| 76 | 77 | // 获得 Deployment Map |
| 77 | 78 | Set<String> deploymentIds = new HashSet<>(); |
| 78 | - processDefinitions.forEach(definition -> CollectionUtils.addIfNotNull(deploymentIds, definition.getDeploymentId())); | |
| 79 | + processDefinitions.forEach(definition -> addIfNotNull(deploymentIds, definition.getDeploymentId())); | |
| 79 | 80 | Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds); |
| 80 | 81 | |
| 81 | 82 | // 获得 BpmProcessDefinitionDO Map |
| 82 | 83 | List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds( |
| 83 | 84 | convertList(processDefinitions, ProcessDefinition::getId)); |
| 84 | - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = CollectionUtils.convertMap(processDefinitionDOs, | |
| 85 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs, | |
| 85 | 86 | BpmProcessDefinitionExtDO::getProcessDefinitionId); |
| 86 | 87 | |
| 87 | 88 | // 获得 Form Map |
| 88 | - Set<Long> formIds = CollectionUtils.convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId); | |
| 89 | + Set<Long> formIds = convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId); | |
| 89 | 90 | Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds); |
| 90 | 91 | |
| 91 | 92 | // 拼接结果 |
| ... | ... | @@ -109,7 +110,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ |
| 109 | 110 | // 获得 BpmProcessDefinitionDO Map |
| 110 | 111 | List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds( |
| 111 | 112 | convertList(processDefinitions, ProcessDefinition::getId)); |
| 112 | - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = CollectionUtils.convertMap(processDefinitionDOs, | |
| 113 | + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs, | |
| 113 | 114 | BpmProcessDefinitionExtDO::getProcessDefinitionId); |
| 114 | 115 | // 执行查询,并返回 |
| 115 | 116 | return BpmProcessDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap); |
| ... | ... | @@ -152,11 +153,11 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ |
| 152 | 153 | @Override |
| 153 | 154 | public List<Deployment> getDeployments(Set<String> ids) { |
| 154 | 155 | if (CollUtil.isEmpty(ids)) { |
| 155 | - return Collections.emptyList(); | |
| 156 | + return emptyList(); | |
| 156 | 157 | } |
| 157 | 158 | List<Deployment> list = new ArrayList<>(ids.size()); |
| 158 | 159 | for (String id : ids) { |
| 159 | - CollectionUtils.addIfNotNull(list, getDeployment(id)); | |
| 160 | + addIfNotNull(list, getDeployment(id)); | |
| 160 | 161 | } |
| 161 | 162 | return list; |
| 162 | 163 | } |
| ... | ... | @@ -169,7 +170,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ |
| 169 | 170 | @Override |
| 170 | 171 | public List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds) { |
| 171 | 172 | if (CollUtil.isEmpty(deploymentIds)) { |
| 172 | - return Collections.emptyList(); | |
| 173 | + return emptyList(); | |
| 173 | 174 | } |
| 174 | 175 | return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list(); |
| 175 | 176 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java
| ... | ... | @@ -86,9 +86,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 86 | 86 | // 设置流程名字 |
| 87 | 87 | runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); |
| 88 | 88 | |
| 89 | - // TODO 芋艿:临时使用, 保证分配 | |
| 90 | -// List<Task> tasks = taskService.getTasksByProcessInstanceId(instance.getId()); | |
| 91 | -// tasks.forEach(task -> taskService.updateTaskAssign(task.getId(), userId)); | |
| 89 | + // 补全流程实例的拓展表 | |
| 90 | + processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()) | |
| 91 | + .setFormVariables(createReqVO.getVariables())); | |
| 92 | 92 | |
| 93 | 93 | // 添加初始的评论 TODO 芋艿:在思考下 |
| 94 | 94 | // Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult(); |
| ... | ... | @@ -98,9 +98,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 98 | 98 | // String type = "normal"; |
| 99 | 99 | // taskService.addComment(task.getId(), instance.getProcessInstanceId(), type, |
| 100 | 100 | // String.format("%s 发起流程申请", user.getNickname())); |
| 101 | -// // TODO 芋艿:应该不用下面两个步骤 | |
| 102 | -//// taskService.setAssignee(task.getId(), String.valueOf(userId)); | |
| 103 | -//// taskService.complete(task.getId(), variables); | |
| 104 | 101 | // } |
| 105 | 102 | return instance.getId(); |
| 106 | 103 | } | ... | ... |
yudao-admin-server/src/main/resources/processes/leave-update.bpmn_bak renamed to yudao-admin-server/src/main/resources/processes/oa-leave.bpmn_bak
yudao-admin-ui/src/views/bpm/definition/index.vue
| ... | ... | @@ -15,11 +15,14 @@ |
| 15 | 15 | <span>{{ getDictDataLabel(DICT_TYPE.BPM_MODEL_CATEGORY, scope.row.category) }}</span> |
| 16 | 16 | </template> |
| 17 | 17 | </el-table-column> |
| 18 | - <el-table-column label="表单信息" align="center" prop="formId"> | |
| 18 | + <el-table-column label="表单信息" align="center" prop="formType" width="200"> | |
| 19 | 19 | <template slot-scope="scope"> |
| 20 | 20 | <el-button v-if="scope.row.formId" type="text" @click="handleFormDetail(scope.row)"> |
| 21 | 21 | <span>{{ scope.row.formName }}</span> |
| 22 | 22 | </el-button> |
| 23 | + <el-button v-else-if="scope.row.formCustomCreatePath" type="text" @click="handleFormDetail(scope.row)"> | |
| 24 | + <span>{{ scope.row.formCustomCreatePath }}</span> | |
| 25 | + </el-button> | |
| 23 | 26 | <label v-else>暂无表单</label> |
| 24 | 27 | </template> |
| 25 | 28 | </el-table-column> |
| ... | ... | @@ -134,16 +137,19 @@ export default { |
| 134 | 137 | }, |
| 135 | 138 | /** 流程表单的详情按钮操作 */ |
| 136 | 139 | handleFormDetail(row) { |
| 137 | - getForm(row.formId).then(response => { | |
| 140 | + // 流程表单 | |
| 141 | + if (row.formId) { | |
| 138 | 142 | // 设置值 |
| 139 | - const data = response.data | |
| 140 | 143 | this.detailForm = { |
| 141 | - ...JSON.parse(data.conf), | |
| 142 | - fields: decodeFields(data.fields) | |
| 144 | + ...JSON.parse(row.formConf), | |
| 145 | + fields: decodeFields(row.formFields) | |
| 143 | 146 | } |
| 144 | 147 | // 弹窗打开 |
| 145 | 148 | this.detailOpen = true |
| 146 | - }) | |
| 149 | + // 业务表单 | |
| 150 | + } else if (row.formCustomCreatePath) { | |
| 151 | + this.$router.push({ path: row.formCustomCreatePath}); | |
| 152 | + } | |
| 147 | 153 | }, |
| 148 | 154 | /** 流程图的详情按钮操作 */ |
| 149 | 155 | handleBpmnDetail(row) { | ... | ... |
yudao-admin-ui/src/views/bpm/model/index.vue
| ... | ... | @@ -50,11 +50,14 @@ |
| 50 | 50 | <span>{{ getDictDataLabel(DICT_TYPE.BPM_MODEL_CATEGORY, scope.row.category) }}</span> |
| 51 | 51 | </template> |
| 52 | 52 | </el-table-column> |
| 53 | - <el-table-column label="表单信息" align="center" prop="formId"> | |
| 53 | + <el-table-column label="表单信息" align="center" prop="formType" width="200"> | |
| 54 | 54 | <template slot-scope="scope"> |
| 55 | 55 | <el-button v-if="scope.row.formId" type="text" @click="handleFormDetail(scope.row)"> |
| 56 | 56 | <span>{{ scope.row.formName }}</span> |
| 57 | 57 | </el-button> |
| 58 | + <el-button v-else-if="scope.row.formCustomCreatePath" type="text" @click="handleFormDetail(scope.row)"> | |
| 59 | + <span>{{ scope.row.formCustomCreatePath }}</span> | |
| 60 | + </el-button> | |
| 58 | 61 | <label v-else>暂无表单</label> |
| 59 | 62 | </template> |
| 60 | 63 | </el-table-column> |
| ... | ... | @@ -450,16 +453,22 @@ export default { |
| 450 | 453 | }, |
| 451 | 454 | /** 流程表单的详情按钮操作 */ |
| 452 | 455 | handleFormDetail(row) { |
| 453 | - getForm(row.formId).then(response => { | |
| 454 | - // 设置值 | |
| 455 | - const data = response.data | |
| 456 | - this.detailForm = { | |
| 457 | - ...JSON.parse(data.conf), | |
| 458 | - fields: decodeFields(data.fields) | |
| 459 | - } | |
| 460 | - // 弹窗打开 | |
| 461 | - this.detailOpen = true | |
| 462 | - }) | |
| 456 | + // 流程表单 | |
| 457 | + if (row.formId) { | |
| 458 | + getForm(row.formId).then(response => { | |
| 459 | + // 设置值 | |
| 460 | + const data = response.data | |
| 461 | + this.detailForm = { | |
| 462 | + ...JSON.parse(data.conf), | |
| 463 | + fields: decodeFields(data.fields) | |
| 464 | + } | |
| 465 | + // 弹窗打开 | |
| 466 | + this.detailOpen = true | |
| 467 | + }) | |
| 468 | + // 业务表单 | |
| 469 | + } else if (row.formCustomCreatePath) { | |
| 470 | + this.$router.push({ path: row.formCustomCreatePath}); | |
| 471 | + } | |
| 463 | 472 | }, |
| 464 | 473 | /** 流程图的详情按钮操作 */ |
| 465 | 474 | handleBpmnDetail(row) { | ... | ... |