# **-二开口子

# 一、后端口子（含RPC/controller/openApi）
## 1、RPC接口

### 1.1、工作流相关

#### 1.1.1、根据多个工作流id，获取工作流基础信息

> 根据多个工作流id获取工作流基础信息，比如工作流名称，描述，状态等  支持根据工作流名称like查询过滤

> 1.1.1.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow\.pathdef.api.rest.path.WfpPathRest#getBaseInfoByIdS

> 1.1.1.2 、入参说明

> **入参说明：**

| 参数名称        | 参数描述    | 必选 | 类型                                             | 说明                 |
| ----------- | :------ | -- | ---------------------------------------------- | ------------------ |
| workflowIds | 工作流id集合 | 是  | List\<Long>                                    |                    |
| user        | 用户对象    | 是  | com.weaver.workflow\.common.entity.org.WeaUser | userid和租户key属性必须有值 |
| otherParam  | 其他参数    | 否  | Map\<String,Object>                            | 其他过滤参数可以放这里        |

> otherParam值说明

otherParam没有可以不传，部分场景需要根据工作流名称过滤的，可以往otherParam中塞一个workflowName参数，会根据指定的名称like查询过滤

> 1.1.1.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpPathRest wfpPathRest;

    public void test() {
        WeaUser user = new WeaUser();
		List<Long> workflowIds = new ArrayList<>();
		Map<String,Object> otherParam = new HashMap<>();
        otherParam.put("workflowName","报销");
    	List<WfpBaseInfoEntity> baseEntityList = wfpPathRest.getBaseInfoByIdS(workflowIds, user,otherParam);
    }
}
```

> 1.1.1.4 、返回值说明

> com.weaver.workflow.common.entity.pathdef.path.base.WfpBaseInfoEntity对象属性说明

```java
	/**
     * 工作流id
     */
    private long id;
    /**
     * 工作流名称
     */
    private String workflowName;
    /**
     * 工作流描述
     */
    private String workflowDesc;
    /**
     * 工作流类型id
     */
    private long workflowType;
    /**
     * 工作流状态
     */
    private WfpBaseStatus status;
    /**
     * 创建时间
     */
    private java.time.LocalDateTime createTime;
    /**
     * 修改时间
     */
    private java.time.LocalDateTime updateTime;
    /**
     * 创建人
     */
    private long creator;
    /**
     * 删除类型
     */
    private int deleteType;
    /**
     * 租户key
     */
    private String tenantKey;
    /**
     * 所属模块
     */
    private int module;
    /**
     * 工作流类别（团队、个人）
     */
    private WfpBelongType belongType;
    /**
     * 流程图类型(0简易模式、1高级模式)
     */
    private Integer chartType;
    /**
     * 显示顺序
     */
    private float orderId;
    /**
     * 分权所属机构id
     */
    private long subCompanyId;
    /**
     * 版本号id
     */
    private int versionId;
    /**
     * 多版本唯一id
     */
    private long fixedVersionId;
    /**
     * 活动版本流程id
     */
    private long activeWfId;
    /**
     * 版本描述
     */
    private String versionDesc;
    /**
     * 流转模式 0固定审批 1自由审批
     */
    private int isFree;

    /**
     * 迁移数据来源，1来源et，2来源ec
     */
    private int datasrc;
    /**
     * 帮助文档id
     */
    private long helpDoc;
  
    /**
     * 流程是否锁定，false不锁定，true锁定
     */
    private int isLock;
    /**
     * 新建流程页面是否默认隐藏，0关闭 1开启
     */
    private int addDefaultHide;
    /**
     * 删除时间
     */
    private java.time.LocalDateTime deleteTime;
    /**
     * 删除人id
     */
    private long deleteUser;
    /**
     * 停用已产生的审批数据
     */
    private int stopFlowData;
    /**
     * 发起端控制: 0 PC端和移动端均可以发起 1仅允许在PC端发起 2仅允许在移动端发起 见WfpCreateClientTypeEnum枚举
     */
    private int createClient;
    /**
     * PC端正常显示: 0未勾选 1勾选
     */
    private int createPcShow;

    /**
     * 移动端正常显示: 0未勾选 1勾选
     */
    private int createMobileShow;
    /**
     * 关联表单模式 0固定表单 1由用户指定表单
     */
    private int relateFormMode;
    /**
     * 工作流标识，用于区分不同服务的工作流
     */
    private String bridgeService;

    /**
     * 工作流搭建方式：0流程图搭建 1权责表搭建
     */
    private int createType;
```
#### 1.1.2、根据单个工作流id，获取工作流基础信息

> 根据单个工作流id，获取工作流信息，如果工作流不存在，则返回null

> 1.1.2.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow\.pathdef.api.rest.path.WfpPathRest#getBaseInfoById

> 1.1.2.2 、入参说明

> **入参说明：**

| 参数名称        | 参数描述    | 必选 | 类型                                             | 说明                 |
| ----------- | :------ | -- | ---------------------------------------------- | ------------------ |
| workflowId | 工作流id | 是  | Long                                    |                    |
| user        | 用户对象    | 是  | com.weaver.workflow.common.entity.org.WeaUser | userid和租户key属性必须有值，如果支持多语言，则languageId属性要传值，代表当前用户语言ID |
| otherParam  | 其他参数    | 否  | Map<String,Object>                            | 预留参数，目前无使用        |


> 1.1.2.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpPathRest wfpPathRest;

    public void test() {
        WeaUser user = new WeaUser();
    	  WfpBaseInfoEntity baseEntity = wfpPathRest.getBaseInfoById(123456789L, user,new HashMap<>());
    }
}
```

> 1.1.2.4 、返回值说明

> com.weaver.workflow.common.entity.pathdef.path.base.WfpBaseInfoEntity对象属性同1.1.1.4节

#### 1.1.3、根据多个工作流id，获取所有版本的工作流id

> 根据多个工作流id，获取所有工作流版本id，比如A工作流有10个版本，B工作流有5个版本，则传入A和B的id，可以查到15个版本的工作流id。

> 1.1.3.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow\.pathdef.api.rest.path.WfpPathRest#getAllVersionWfId

> 1.1.3.2 、入参说明

> **入参说明：**

| 参数名称        | 参数描述    | 必选 | 类型          |
| :---------- | :------ | :- | :---------- |
| workflowIds | 工作流id集合 | 是  | List\<Long> |
| tenantKey   | 租户key   | 是  | String      |

> 1.1.3.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpPathRest wfpPathRest;

    public void test() {
        String tenantKey = user.getTenantKey();
		List<Long> workflowIds = new ArrayList<>();
    	List<Long> allVersionWfId = wfpPathRest.getAllVersionWfId(workflowIds,tenantKey);
    }
}
```
#### 1.1.4、根据单个工作流id，获取所有版本的工作流id

> 根据单个工作流id，获取所有版本的工作流id

> 1.1.4.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow\.pathdef.api.rest.path.WfpPathRest#getAllVersionWfId

> 1.1.4.2 、入参说明

> **入参说明：**

| 参数名称        | 参数描述    | 必选 | 类型                                             | 说明                 |
| ----------- | :------ | -- | ---------------------------------------------- | ------------------ |
| workflowId | 工作流id | 是  | Long                                    |                    |
| user        | 用户对象    | 是  | com.weaver.workflow.common.entity.org.WeaUser | userid和租户key属性必须有值 |
| otherParam  | 其他参数    | 否  | Map<String,Object>                            | 预留参数，目前暂无实际使用        |


> 1.1.4.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpPathRest wfpPathRest;

    public void test() {
        WeaUser user = new WeaUser();
    	List<Long> allVersionWfIds = wfpPathRest.getAllVersionWfId(123456789L, user,new HashMap<>());
    }
}
```

#### 1.1.5、根据多个工作流id，获取每个工作流对应的活动版本id

> 根据多个工作流id，获取每个工作流对应的活动版本id

> 1.1.5.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow\.pathdef.api.rest.path.WfpPathRest#getActiveWfIdMap

> 1.1.5.2 、入参说明

> **入参说明：**

| 参数名称        | 参数描述               | 必选 | 类型          |
| :---------- | :----------------- | :- | :---------- |
| workflowIds | 工作流id集合            | 是  | List\<Long> |
| userId      | 用户id，employee对象的id | 是  | long        |

> 1.1.5.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpPathRest wfpPathRest;

    public void test() {
        String userId = user.getUserId();
		List<Long> workflowIds = new ArrayList<>();
    	Map<Long,Long> allVersionWfId = wfpPathRest.getActiveWfIdMap(workflowIds,userId );
    }
}
```

> 1.1.5.4 、返回值说明

> key是工作流id，value是活动版本id


#### 1.1.6、根据单个工作流id，获取活动版本id

> 根据单个工作流id，获取活动版本id

> 1.1.6.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.path.WfpPathRest#getActiveWfId

> 1.1.6.2 、入参说明

> **入参说明：**

| 参数名称        | 参数描述    | 必选 | 类型                                             | 说明                 |
| ----------- | :------ | -- | ---------------------------------------------- | ------------------ |
| workflowId | 工作流id | 是  | Long                                    |                    |
| user        | 用户对象    | 是  | com.weaver.workflow.common.entity.org.WeaUser | userid和租户key属性必须有值 |
| otherParam  | 其他参数    | 否  | Map<String,Object>                            | 预留参数，目前暂无实际使用        |


> 1.1.6.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpPathRest wfpPathRest;

    public void test() {
        WeaUser user = new WeaUser();
    	long activeWfId = wfpPathRest.getActiveWfId(123456789L, user,new HashMap<>());
    }
}
```

#### 1.1.7、根据条件获取租户下所有工作流信息

> 获取当前租户下所有工作流基础信息，包括工作流名称、描述、状态等，支持多语言
>
> 支持获取团队工作流、个人工作流、工作流模版

> 1.1.7.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.path.WfpPathRest#getBaseInfoByBelongType

> 1.1.7.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| belongType | 工作流所属类型            | 是  | WfpBelongType枚举 |
| userId | 用户id，employee对象的id | 是  | long        |
| otherParam | 其它扩展参数，比如增加自定义的过滤条件 | 否  | Map<String,Object>        |

> 1.1.7.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpPathRest wfpPathRest;

    public void test() {
                List<WfpBaseInfoEntity> entitylist = wfpPathRest.getBaseInfoByBelongType(WfpBelongType.COMPANY, employee.getId(), new HashMap<>());
	}
}
```

> 1.1.7.4 、otherParam参数补充说明

> 此接口默认支持活动版本数据，如果需要根据工作流名称、类型、状态等过滤时，可以往otherParam增加参数

> **支持增加的参数说明：**

| 参数名称   | 参数描述               | 参数值说明        |
| :----- | :----------------- | :---------- |
| status | 工作流状态          | String字符串，多个状态逗号分割，比如status=1,5 具体值见WfpBaseStatus枚举 |
| workflowName | 工作流名称  | String字符串    |
| isFree | 自由流程还是固定流程 | int类型，0固定流程 1自由流程|
| workflowIds | 工作流id集合 | List< Long >类型，多个工作流id的集合|
| workflowTypes | 工作流类型id集合 | List< Long >类型，多个工作流类型id的集合|
| formTypes | 表单类型集合 | String字符串，多个类型逗号分割，formTypes=wea_form 具体值见WfpRelateFormType枚举|
| wfSymbol | 工作流编码 | String字符串|

#### 1.1.8、获取某个人有查看权限的所有工作流

> 考虑了工作流维护权限和工作流菜单查看权限
>
> 支持根据工作流类型、工作流所属机构、工作流名称等条件过滤

> 1.1.8.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.path.WfpPathRest#queryBaseInfoList

> 1.1.8.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| user | 用户对象            | 是  | WeaUser对象，至少要给userId用户id、tenantKey租户key、departMentId部门id，这3个属性 |
| queryCondition | 查询条件 | 是  |    WfpBaseListQueryCondition   |
> **queryCondition对象属性详细说明*：*
```java
   /**
     * 工作流名称，传null代表不限制
     */
    private String workflowName;

    /**
     * 工作流所属机构id，传null代表不限制
     */
    private List<Long> subCompanyIds;

    /**
     * 工作流类型id，过滤其它类型需传-1，传null代表不限制
     */
    private List<Long> workflowTypes;

    /**
     * 是否分页查询，默认true
     */
    private boolean pageQuery = true;

    /**
     * 分页参数，当前页
     */
    private int pageSize = 1;

    /**
     * 分页参数，每页大小
     */
    private int currentPage = 10;

    /**
     * 工作流状态，传null，则默认只查活动版本的工作流
     */
    private List<Integer> status;
```
> 1.1.8.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpPathRest wfpPathRest;

    public void test() {
	WfpBaseListQueryCondition queryCondition = new WfpBaseListQueryCondition();
        //根据机构ID过滤
        List<Long> subCompanyIds = new ArrayList<>();
        subCompanyIds.add(11111L);
        queryCondition.setSubCompanyIds(subCompanyIds);
        List<WfpBaseInfoEntity> entitylist = wfpPathRest.queryBaseInfoList(user, new HashMap<>());
	}
}
```

#### 1.1.9、根据工作流id，自定义更新工作流基础信息

> 根据工作流id，自定义更新工作流基础信息

> 开放部分属性支持更新，目前仅支持更新：工作流所属机构id、支持工作流模版转工作流、工作流类型、工作流名称、工作流描述、工作流排序

> 1.1.9.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.path.WfpPathRest#updateBaseInfoRpc

> 1.1.9.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| user | 用户对象            | 是  | WeaUser对象，至少要给userid和租户key属性 |
| baseInfo | 工作流基础信息 | 是  |    工作流基础信息WfpBaseInfoEntity对象   |
| otherParams | 预留参数 | 否  |  扩展使用，预留参数   |
> **WfpBaseInfoEntity对象属性详细说明*：*
```java
   /**
     * 工作流id，必须传
     */
    private long id;
   /**
     * 工作流所属机构id，非必传，只有传大于0的数据，才会更新
     */
    private long subCompanyId;

    /**
     * 工作流状态，非必传，当otherParams传递convertTemplateToPath=ture时，才会更新状态，支持把工作流模版转工作流
     */
    private WfpBaseStatus status;
    
    /**
     * 工作流类型id，非必传，只有传大于0的数据，才会更新，如果是想更新为其它类型，传-1
     */
    private long workflowType;
```
> 1.1.9.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpPathRest wfpPathRest;

    public void test() {
	        WfpBaseInfoEntity baseInfo = new WfpBaseInfoEntity();
          			//设置工作流id
                baseInfo.setId(999999L);
                //要更新机构id时，才传机构id
                baseInfo.setSubCompanyId(123L);
                Map<String, Object> otherParams = new HashMap<>();
                //把工作流模版转工作流，并且状态设置为启用
                otherParams.put("convertTemplateToPath",true);
                baseInfo.setStatus(WfpBaseStatus.VALID);
                
                
                //设置工作流名称
                baseInfo.setWorkflowName("测试rpc接口更新名称");
                //设置工作流描述
                baseInfo.setWorkflowDesc("测试rpc接口更新描述");
                //设置工作流排序id
                baseInfo.setOrderId(111);
                //封装自定义的更新条件对象
                WfpUpdatePathCondition updateCondition = new WfpUpdatePathCondition();
                //是否需要更新工作流名称，设置为true，才会更新工作流名称
                updateCondition.setNeedUpdateWorkflowName(true);
                //是否需要更新工作流描述，设置为true，才会更新工作流描述
                updateCondition.setNeedUpdateWorkflowDesc(true);
                //是否需要更新工作流排序，设置为true，才会更新工作流排序
                updateCondition.setNeedUpdateOrderId(true);
                otherParams.put("updateCondition",updateCondition);
                //调用接口更新
                WfpUpdateResultEntity result = wfpPathRest.updateBaseInfoRpc(user, baseInfo,otherParams);
     }
}
```
> **WfpUpdatePathCondition对象属性详细说明*：*
```java
   /**
     * 是否更新工作流名称，默认false
     */
    private boolean needUpdateWorkflowName;
    /**
     * 是否更新工作流描述，默认false
     */
    private boolean needUpdateWorkflowDesc;
    /**
     * 是否更新工作流排序，默认false
     */
    private boolean needUpdateOrderId;
```
> 1.1.9.4 、返回结果说明

> **返回结果WfpUpdateResultEntity对象属性详细说明*：*
```java
   /**
     * 更新结果：成功true 失败false
     */
    private boolean success;
    /**
     * 更新成功或者失败的提示信息
     */
    private String msg;
```

#### 1.1.10、把指定工作流id设置为活动版本

> 把指定工作流id设置为活动版本

> 接口会校验工作流状态，只有是历史版本状态的工作流，才会被设置为活动版本

> 1.1.10.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.path.WfpPathRest#activePath

> 1.1.10.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| workflowId | 工作流id            | 是  | long类型 |
| user | 用户对象            | 是  | WeaUser对象，至少要给userid和租户key属性 |
| otherParams | 预留参数 | 否  |  扩展使用，预留参数   |
> 1.1.10.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpPathRest wfpPathRest;

    public void test() {
	WeaUser user = new WeaUser();
        user.setUserId(1111L);
        user.setTenantKey("abcdsas");
        //把id=1055612032852566100的工作流设置为活动版本
        boolean success = wfpPathRest.activePath(1055612032852566100L,user, new HashMap<>());
     }
}
```
> 1.1.10.4 、返回结果说明

> true代表成功，false代表失败

#### 1.1.11、把指定工作流id设置为停用或启用

> 把指定工作流id设置为停用或启用

> 接口会校验工作流状态，只有是停用或启用状态的，才能被切换状态

> 1.1.11.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.path.WfpPathRest#enableOrStopPath

> 1.1.11.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| workflowId | 工作流id            | 是  | long类型 |
| status | 工作流状态  1启用 5停用         | 是  | int类型 |
| user | 用户对象            | 是  | WeaUser对象，至少要给userid和租户key属性 |
| otherParams | 预留参数 | 否  |  扩展使用，预留参数   |
> 1.1.11.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpPathRest wfpPathRest;

    public void test() {
	WeaUser user = new WeaUser();
        user.setUserId(1111L);
        user.setTenantKey("abcdsas");
        //把id=1055612032852566100的工作流设置为停用状态
        boolean success = wfpPathRest.enableOrStopPath(1012200169804054528L, 5, user, new HashMap<>());

     }
}
```
> 1.1.11.4 、返回结果说明

> true代表成功，false代表失败

#### 1.1.12、给指定工作流添加权限设置

> 支持工作流维护权限、统计权限、统计数据导出权限

> 接口会校验重复数据，比如权限设置已经存在这个角色，第二次在新增这个角色时不会再重复添加。

> 1.1.12.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.path.WfpPathRest#addPathAuth

> 1.1.12.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| workflowId | 工作流id            | 是  | long类型 |
| authType | 权限类型         | 是  | WfpAuthTypeEnum枚举 |
| orgList | 权限的人员组织配置数据| 是  | List，WfpMultiOrgRpcEntity对象集合 |
| user | 用户对象            | 是  | WeaUser对象，至少要给userid和租户key属性 |
| otherParams | 预留参数 | 否  |  扩展使用，预留参数   |
> 1.1.12.3、WfpMultiOrgRpcEntity对象详细属性说明
```java
   /**
     * 数据对应值，如人员id、部门id。必须传
     */
    private long orgId;

    /**
     * 数据类型，0人员；1部门；2分部；3常用组；4角色；5岗位；6所有人，见MultiOrgTypeEnum枚举。必须传
     */
    private int orgType;

    /**
     * 数据对应的名称，如人员名称、部门名称，必须传
     */
    private String name;
```
> 1.1.12.4、调用示例

> 以给指定工作流权限设置添加人员、部门、分部、群组、角色、所有人，全量的数据为例

> 实际使用时，不一定是全量添加，可能只添加一个角色，则只给角色信息即可。

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpPathRest wfpPathRest;

    public void test() {
	WeaUser user = new WeaUser();
        user.setUserId(1111L);
        user.setTenantKey("abcdsas");
        //人员
        List<WfpMultiOrgRpcEntity> orgList = new ArrayList<>();
        WfpMultiOrgRpcEntity orgRpcEntity1 = new WfpMultiOrgRpcEntity();
        orgRpcEntity1.setOrgId(861918181638316032L);
        orgRpcEntity1.setName("张三");
        orgRpcEntity1.setOrgType(MultiOrgTypeEnum.PERSON.getType());
        orgList.add(orgRpcEntity1);
        //部门
        WfpMultiOrgRpcEntity orgRpcEntity2 = new WfpMultiOrgRpcEntity();
        orgRpcEntity2.setOrgId(878588315601092622L);
        orgRpcEntity2.setName("smc部门");
        orgRpcEntity2.setOrgType(MultiOrgTypeEnum.DEPARTMENT.getType());
        orgList.add(orgRpcEntity2);
        //分部
        WfpMultiOrgRpcEntity orgRpcEntity3 = new WfpMultiOrgRpcEntity();
        orgRpcEntity3.setOrgId(861917357189144576L);
        orgRpcEntity3.setName("审批流程组开发测试团队");
        orgRpcEntity3.setOrgType(MultiOrgTypeEnum.SUBCOMPANY.getType());
        orgList.add(orgRpcEntity3);
        //群组
        WfpMultiOrgRpcEntity orgRpcEntity4 = new WfpMultiOrgRpcEntity();
        orgRpcEntity4.setOrgId(871571863732322304L);
        orgRpcEntity4.setName("流程组");
        orgRpcEntity4.setOrgType(MultiOrgTypeEnum.COMMON_GROUP.getType());
        orgList.add(orgRpcEntity4);
        //角色
        WfpMultiOrgRpcEntity orgRpcEntity5 = new WfpMultiOrgRpcEntity();
        orgRpcEntity5.setOrgId(861917361414840320L);
        orgRpcEntity5.setName("系统管理员");
        orgRpcEntity5.setOrgType(MultiOrgTypeEnum.ROLE.getType());
        orgList.add(orgRpcEntity5);
        //所有人
        WfpMultiOrgRpcEntity orgRpcEntity6 = new WfpMultiOrgRpcEntity();
        orgRpcEntity6.setOrgId(0L);
        orgRpcEntity6.setName("所有人");
        orgRpcEntity6.setOrgType(MultiOrgTypeEnum.ALL.getType());
        orgList.add(orgRpcEntity6);
        //给工作流id=1012200169804054528的工作流，添加工作流维护权限
        boolean b1 = wfpPathRest.addPathAuth(1012200169804054528L, WfpAuthTypeEnum.PATH, orgList, user, new HashMap<>());
        //给工作流id=1012200169804054528的工作流，添加统计数据导出权限
        boolean b2 = wfpPathRest.addPathAuth(1012200169804054528L, WfpAuthTypeEnum.OUTPUT, orgList, user, new HashMap<>());
        //给工作流id=1012200169804054528的工作流，添加统计权限
        boolean b3 = wfpPathRest.addPathAuth(1012200169804054528L, WfpAuthTypeEnum.STATISTICS, orgList, user, new HashMap<>());
     }
}
```
> 1.1.12.5 、返回结果说明

> true代表成功，false代表失败

#### 1.1.13、工作流存为新版

> 团队工作流才支持存为新版，个人（成员）工作流不支持存为新版，工作流模版也不支持存为新版

> 接口默认会校验工作流编辑权限，有权限的才能存为新版，支持调用方传参不校验权限

> 接口默认会校验租户付费，会限制未付费租户最多只能创建6条工作流，支持调用方传参不校验付费

> 1.1.13.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.path.WfpPathRest#createNewVersion

> 1.1.13.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| params | 工作流存为新版时的参数  | 是  | WfpCreateNewVersionParam对象 |
| user | 用户对象            | 是  | WeaUser对象，至少要给userid和租户key属性 |
> 1.1.13.3、WfpCreateNewVersionParam对象属性详细说明
```java
   /**
     * 工作流id，必传
     */
    private long workflowId;

    /**
     * 版本描述，可选
     */
    private String versionDesc;
    
    /**
     * 是否需要校验权限
     * 默认true，需要校验创建权限
     */
    private boolean checkAuth = true;

    /**
     * 是否校验租户付费
     * 如果租户未购买流程模块，则免费租户最多只能创建6条工作流
     * 默认true，要校验付费
     */
    private boolean checkPay = true;

    /**
     * 调用来源信息，可选
     * 用于说明是什么功能调用的这个接口，会被记录到操作日志中，方便追溯工作流来源，比如传“XX二开功能调用”
     */
    private String src;
```
> 1.1.13.4、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpPathRest wfpPathRest;

    public void test() {
				WeaUser user = new WeaUser();
        user.setUserId(1111L);
        user.setTenantKey("abcdsas");
        WfpCreateNewVersionParam params = new WfpCreateNewVersionParam();
        //要存为新版的工作流id，必须传
        params.setWorkflowId(1055612032852566100L);
        //新版本的描述信息，可选
        params.setVersionDesc("版本描述信息");
        //调用来源说明
        params.setSrc("XX二开功能调用");
        WfpCreateNewVersionResult newVersion = wfpPathRest.createNewVersion(params, user);
     }
}
```
> 1.1.13.5 、返回结果说明

> WfpCreateNewVersionResult对象属性说明
```java
   /**
     * 存为新版结果：成功true 失败false
     */
    private boolean success;

    /**
     * 新的工作流id
     */
    private long newWorkflowId;

    /**
     * 成功或者失败的提示信息
     */
    private String msg;

    /**
     * 新老节点id映射关系
     *
     */
    private Map<Long, Long> nodeIdMapping;

    /**
     * 新老出口id映射关系
     */
    private Map<Long, Long> linkIdMapping;
```
#### 1.1.14、新建工作流

> 支持调用方预设工作流id，如果传了id，则会取传的作为工作流主键id

> 支持调用方新建自定义的节点和出口信息

> 支持创建关联eb卡片的工作流

> 接口默认会校验工作流新建权限（支持考虑分权，校验对指定机构id是否有权限），有权限的才能新建，支持调用方传参不校验权限

> 接口默认会校验租户付费，会限制未付费租户最多只能创建6条工作流，支持调用方传参不校验付费


> 1.1.14.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.path.WfpPathRest#createPath

> 1.1.14.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| baseInfo | 工作流基础信息  | 是  | WfpBaseInfoEntity对象 |
| params | 新建工作流的其它参数  | 是  | WfpCreatePathParam对象 |
| user | 用户对象  | 是  | WeaUser对象，至少要给userid和租户key属性 |
> 1.1.12.3、WfpBaseInfoEntity对象属性详细说明
```java

       /**
     * 工作流id，可选，如果不传，则会自动生成，如果传了，则会取传的作为工作流主键id
     */
    private long id;

    /**
     * 工作流名称，必传
     */
    private String workflowName;

    /**
     * 工作流所属类型（团队还是个人），必传
     */
    private WfpBelongType belongType;

    /**
     * 工作流描述，可选
     */
    private String workflowDesc;

    /**
     * 工作流类型id，可选  不传则工作流是创建到其它类型下面
     */
    private long workflowType;

    /**
     * 工作流标识，用于区分不同服务的工作流，可选 不传则会根据表单类型自动计算
     */
    private String bridgeService;

    /**
     * 新建流程页面是否默认隐藏，可选的  0关闭 1开启
     */
    private int addDefaultHide;

    /**
     * 工作流显示顺序，可选
     */
    private float orderId;

    /**
     * 工作流流转模式 0固定流程 1自由流程，可选 默认是固定流程
     */
    private int isFree;

    /**
    * 工作流编码，可选
    */
    private String wfSymbol;

    /**
     * 工作流状态，可选，支持调用方传递启用或者停用状态，不传，则默认创建的是启用状态的工作流
     */
    private WfpBaseStatus status;
```
> 1.1.14.4、WfpCreatePathParam对象属性详细说明
```java

    /**
     * 表单id，必传
     */
    private long formId;

    /**
     * 表单类型，必传
     */
    private WfpRelateFormType formType;

    /**
     * 应用id，只有创建eb工作流时使用，非eb工作流，不用传
     */
    private long appId;

    /**
     * 自定义的节点信息，可选
     */
    private List<AddNodeRpcEntity> nodeList;

    /**
     * 自定义的出口信息，可选
     */
    private List<AddNodeLinkRpcEntity> linkList;
    
    /**
     * 是否需要校验权限
     * 默认true，需要校验创建权限
     */
    private boolean checkAuth = true;
    
     /**
     * 当需要校验创建权限时，是否需要考虑分权
     * 默认false不考虑分权
     */
    private boolean checkDetachable = false;

    /**
     * 当需要校验创建权限且考虑分权时，传的分权机构id
     */
    @JsonSerialize(using = ToStringSerializer.class)
    private long subCompanyId;
    
    /**
     * 是否校验租户付费
     * 如果租户未购买流程模块，则免费租户最多只能创建6条工作流
     * 默认true，要校验付费
     */
    private boolean checkPay = true;

    /**
     * 调用来源信息，可选
     * 用于说明是什么功能调用的这个接口，会被记录到操作日志中，方便追溯工作流来源，比如传“XX二开功能调用”
     */
    private String src;

   
```
> 1.1.14.5、AddNodeRpcEntity对象属性详细说明
```java
		@ApiModelProperty("节点id-主键，可选  如果不传 就自动生成")
    private long id;

    @ApiModelProperty("节点名称，必传")
    private String nodeName;

    @ApiModelProperty("节点类型，必传 0-发起,1-审批,2-确认,3-结束,5-投票,7-自动处理,8-等待")
    private int nodeType;

    @ApiModelProperty("节点属性，必传 0-一般节点,1-分流点,2-分流中间点,3-合流点")
    private int nodeAttr;

    @ApiModelProperty("节点排序，可选")
    private int orderId;
   
```
> 1.1.14.6、AddNodeLinkRpcEntity对象属性详细说明
```java

    @ApiModelProperty("出口id-主键  如果不传 就自动生成")
    private long id;

    @ApiModelProperty("出口名称，必传")
    private String linkName;

    @ApiModelProperty("源节点，必传")
    private long srcNodeId;

    @ApiModelProperty("目标节点，必传")
    private long destNodeId;

    @ApiModelProperty("是否退回出口，可选")
    private int isReject;

    @ApiModelProperty("排序，可选")
    private float orderId;

    @ApiModelProperty("出口条件ID，可选")
    private long conditionKey;

   
```
> 1.1.14.7、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpPathRest wfpPathRest;

    public void test() {
				WeaUser user = new WeaUser();
        user.setUserId(1111L);
        user.setTenantKey("abcdsas");
        //1、封装工作流基础信息
        WfpBaseInfoEntity baseInfo = new WfpBaseInfoEntity();
        baseInfo.setWorkflowName("工作流名称XX");
        baseInfo.setWorkflowDesc("工作流描述XX");
        //机构id
        baseInfo.setSubCompanyId(1111L);
        //设置类型是团队工作流
        baseInfo.setBelongType(WfpBelongType.COMPANY);
        //设置工作流状态为停用
        baseInfo.setStatus(WfpBaseStatus.INVALID);
        //设置工作流编码
        baseInfo.setWfSymbol("工作流编码XX");
        
        //2、封装表单相关参数
        WfpCreatePathParam param = new WfpCreatePathParam();
        //表单id
        param.setFormId(1019157243698413570L);
        //表单类型
        param.setFormType(WfpRelateFormType.WEA_FORM);
        //如果是eb表单，还要传appId
//        param.setFormType(WfpRelateFormType.WEA_EBUILDER);
//        param.setAppId(920891888144482306L);

        //3、封装权限校验信息
        //校验权限
        param.setCheckAuth(false);
        //是否考虑分权
        param.setCheckDetachable(false);
        //如果考虑分权，传机构id
        param.setSubCompanyId(111111L);
        //是否校验付费
        param.setCheckPay(false);

        //4、封装来源信息
        param.setSrc("二开XX功能调用");
        
        //5、封装自定义的节点和出口信息
        //自定义的节点信息
        List<AddNodeRpcEntity> nodeList = new ArrayList<>();
        nodeList.add(new AddNodeRpcEntity(11111111111L, "发起节点", WfpNodeType.START.getType(), WfpNodeAttr.COMMON.getCode(), 1));
        nodeList.add(new AddNodeRpcEntity(11111111112L, "1级审批", WfpNodeType.APPROVE.getType(), WfpNodeAttr.COMMON.getCode(), 2));
        //可以不传节点id，不传则自动生成，传了则取传的
        nodeList.add(new AddNodeRpcEntity( "2级审批", WfpNodeType.APPROVE.getType(), WfpNodeAttr.COMMON.getCode(), 3));
        nodeList.add(new AddNodeRpcEntity(11111111113L, "结束节点", WfpNodeType.END.getType(), WfpNodeAttr.COMMON.getCode(), 4));
        param.setNodeList(nodeList);
        //自定义的出口信息
        List<AddNodeLinkRpcEntity> linkList = new ArrayList<>();
        linkList.add(new AddNodeLinkRpcEntity(1111L, "发起节点 至 1级审批", 11111111111L, 11111111112L, 0,1,0));
        linkList.add(new AddNodeLinkRpcEntity( "发起节点 至 结束节点", 11111111111L, 11111111113L, 0,2,0));
        linkList.add(new AddNodeLinkRpcEntity(1113L, "1级审批 至 结束节点", 11111111112L, 11111111113L, 0,3,0));
        param.setLinkList(linkList);
        
        WfpCreateResultEntity result = wfpPathRest.createPath(baseInfo, param, user);
     }
}
```
> 1.1.14.8 、返回结果说明

> WfpCreateResultEntity对象属性说明
```java
   /**
     * 工作流id:创建失败返回-1
     */
    private long workflowId;

    /**
     * 工作流跟表单关联表的主键ID
     */
    private long relateFormId;
    /**
     * 创建结果：成功true 失败false
     */
    private boolean success;
    /**
     * 创建成功或者失败的提示信息
     */
    private String msg;
```



### 1.2、工作流节点相关


#### 1.2.1、根据工作流id，获取工作流下所有节点

> 根据工作流id，获取工作流下所有的节点信息，比如节点名称，节点类型，节点描述等信息
>
> 包括固定节点和自由节点

> 1.2.1.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow\.pathdef.api.rest.pathnode.WfpNodeRest#getNodeBaseListInfo

> 1.2.1.2 、入参说明

> **入参说明：**

| 参数名称       | 参数描述                    | 必选 | 类型          |
| :--------- | :---------------------- | :- | :---------- |
| workflowId | 工作流id                   | 是  | long |
| userId     | 用户id，employee对象的id      | 是  | long        |

> 1.2.1.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpNodeRest wfpNodeRest;

    public void test() {
		List<WfpNodeBaseEntity> nodes = wfpNodeRest.getNodeBaseListInfo(workflowId,employee.getId());
	}
}
```

> 1.2.1.4 、返回值说明

> 注意此接口支持返回固定节点信息和自由节点，只有当requestId>0时，才会查询自由节点

> com.weaver.workflow\.common.entity.pathdef.pathnode.base.WfpNodeBaseEntity对象属性说明

```java
	/**
     * 节点id
     */
    private long id;
    /**
     * 工作流id
     */
    private long workflowId;
    /**
     * 自由流程-请求id
     */
    private long requestId;
    /**
     * 自由流程-父节点id
     */
    private long parentNodeId;
    /**
     * 节点名称
     */
    private String nodeName;
    /**
     * 节点类型
     */
    private WfpNodeType nodeType;
    /**
     * 节点属性
     */
    private WfpNodeAttr nodeAttr;
    /**
     * 创建时间
     */
    private java.time.LocalDateTime createTime;
    /**
     * 修改时间
     */
    private java.time.LocalDateTime updateTime;
    /**
     * 创建人
     */
    private long creator;
    /**
     * 删除类型
     */
    private int deleteType=0;
    /**
     * 租户key
     */
    private String tenantKey;
    /**
     * 排序
     */
    private float orderId;
    /**
     * 分支第一个分叉起始节点
     */
    private long branchStartNodeId;

    /**
     * 允许新增审批人员
     */
    private int createAllowAddOperator;

    /**
     * 允许新增审批环节
     */
    private int createAllowAddNode;

    /**
     * 数据来源
     */
    private int datasrc;

    /**
     * 自由流程退回后，历史已流转的节点需要更新为1，标识该节点不再可到达
     */
    private int isDied;
	/**
     * 源节点
     */
    private long sourceNodeid;
    /**
     * 加签节点是否可修改审批表内容
     */
    private int isModifiable;
	/**
     * 分叉起始节点
     */
    private long groupid;
    /**
     * 来源，标志在哪个场景增加的节点
     */
    private int source;
    /**
     * 公共属性：0工作流节点 1公共节点 2流转片段中的节点 见WfpNodePublicAttrEnum枚举
     */
    private int publicAttr;
    /**
     * 关联的片段id，可能是公共流转片段id或者权责表id：只有当此节点是从公共节点复制而来的时候才有值
     */
    private long publicSegmentId;
    /**
     * 关联的公共节点id：只有当此节点是从公共节点复制而来的时候才有值
     */
    private long publicNodeId;
    /**
     * 节点描述
     */
    private String nodeDesc;
    /**
     * 流转片段中nodeid
     */
    private long publicSegNodeId;
```

#### 1.2.2、根据工作流节点id，获取节点基础信息

> 根据工作流节点id，获取节点基础信息，比如节点名称，节点类型，节点描述等信息
>
> 支持固定节点和自由节点

> 1.2.2.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.pathnode.WfpNodeRest#getNodeBaseById(long, com.weaver.workflow.common.entity.org.WeaUser)

> 1.2.2.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| nodeId | 工作流节点id            | 是  | long |
| user | 用户对象，至少要给userId和租户key属性，需要节点名称支持多语言时，需要传languageId属性，代表语言ID | 是  | WeaUser        |

> 1.2.2.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpNodeRest wfpNodeRest;

    public void test() {
    	WeaUser user = new WeaUser();
        //用户ID，employee对象的id属性
        user.setUserId(employee.getId());
        //租户key
        user.setTenantKey(tenantKey);
        //语言ID
        user.setLanguageId(languageId);
	WfpNodeBaseEntity nodeBaseEntity = wfpNodeRest.getNodeBaseById(nodeId, user);
}
}
```

> 1.2.2.4 、返回值说明

> 此接口支持查询固定节点信息和自由节点

> com.weaver.workflow.common.entity.pathdef.pathnode.base.WfpNodeBaseEntity对象属性同1.2.1.4节


### 1.3、工作流类型相关

#### 1.3.1、获取租户下所有工作流类型基础信息

> 根据租户key和用户id获取当前租户下所有工作流类型基础信息，类型名称和描述支持多语言

> 1.3.1.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow\.pathdef.api.rest.type.WfpTypeSetRest#getTypeInfoList

> 1.3.1.2 、入参说明

> **入参说明：**

| 参数名称      | 参数描述               | 必选 | 类型     |
| :-------- | :----------------- | :- | :----- |
| tenantKey | 租户key              | 是  | String |
| userId    | 用户id，employee对象的id | 是  | long   |

> 1.3.1.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpTypeSetRest wfpTypeSetRest;

    public void test() {
        List<WfpTypeInfoEntity> typeList = wfpTypeSetRest.getTypeInfoList(employee.getTenantKey(), employee.getEmployeeId());
    }
}
```

> 1.3.1.4 、返回值说明

> 此接口会返回一个虚拟的类型，叫其它类型，类型id=-1
>
> com.weaver.workflow.common.entity.pathdef.type.WfpTypeInfoEntity对象属性说明

```java
	/**
     * 类型id
     */
    private long id;
    /**
     *类型名称
     */
    private String typeName;
    /**
     * 创建时间
     */
    private java.time.LocalDateTime createTime;
    /**
     * 修改时间
     */
    private java.time.LocalDateTime updateTime;
    /**
     * 创建人
     */
    private  long  creator;
    /**
     * 删除类型
     */
    private int deleteType=0;
    /**
     * 租户key
     */
    private String tenantKey;
    /**
     * 排序
     */
    private float orderId=0f;
    /**
     * 类型描述
     */
    private String typeDesc;
    /**
     * 类型图标
     */
    private String iconKey;
    /**
     * 分权所属机构
     */
    private long subCompanyId;
    /**
     * 所属模块
     */
    private int module;
    /**
     * 所属类型（团队、个人）
     */
    private WfpBelongType belongType;
    /**
     * 类型图标id
     */
    private int iconId;
```
#### 1.3.2、根据多个类型id，获取工作流类型基础信息

> 根据多个类型id，获取工作流类型基础信息，类型名称和描述支持多语言

> 1.3.2.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow\.pathdef.api.rest.type.WfpTypeSetRest#getWfpTypeInfoByIds

> 1.3.2.2 、入参说明

> **入参说明：**

| 参数名称    | 参数描述               | 必选 | 类型          |
| :------ | :----------------- | :- | :---------- |
| typeIds | 多个类型id             | 是  | List\<Long> |
| userId  | 用户id，employee对象的id | 是  | long        |

> 1.3.2.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpTypeSetRest wfpTypeSetRest;

    public void test() {
		List<Long> typeIds = new ArrayList();
 		typeIds.add(1111);
 		typeIds.add(2222);
        List<WfpTypeInfoEntity> wfpTypeInfoEntities = wfpTypeSetRest.getWfpTypeInfoByIds(typeIds,employee.getEmployeeId());

}
}
```

> 1.3.2.4 、返回值说明

> 注意此接口不会返回其它类型，只会查数据库中Wfp\_type表真实存在的数据

> com.weaver.workflow.common.entity.pathdef.type.WfpTypeInfoEntity对象属性同1.3.1.4节

#### 1.3.3、根据单个id获取工作流类型基础信息

> 根据单个id获取工作流类型基础信息，默认不支持返回其它类型

> 1.3.3.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.type.WfpTypeSetRest#getWfpTypeInfoById

> 1.3.3.2 、入参说明

> **入参说明：**

| 参数名称        | 参数描述    | 必选 | 类型                                             | 说明                 |
| ----------- | :------ | -- | ---------------------------------------------- | ------------------ |
| typeId | 工作流类型id | 是  | Long                                    |                    |
| user        | 用户对象    | 是  | com.weaver.workflow.common.entity.org.WeaUser | userid和租户key属性必须有值 |
| otherParam  | 其他参数    | 否  | Map<String,Object>                            |         |

> otherParam参数说明

当typeId<=0时，默认返回null，如果需要返回其它类型，则otherParam需要手动传needOtherType=true，才会返回其它类型

> 1.3.3.3、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    WfpTypeSetRest typeSetRest;

    public void test() {
        WeaUser user = new WeaUser();
		Map<String,Object> otherParam = new HashMap<>();
        otherParam.put("needOtherType",true);
    	WfpTypeInfoEntity entity = wfpPathRest.getWfpTypeInfoById(123456789L, user,new HashMap<>());
    }
}
```
> 1.3.3.4、返回值说明

> com.weaver.workflow.common.entity.pathdef.type.WfpTypeInfoEntity对象属性同1.3.1.4节

#### 1.3.4、新建工作流类型

> 支持个人类型和团队类型

> 当新建团队类型时，接口会校验类型名称不允许重复

> 当新建团队类型时，如果租户开启分权，则新建时，必须传机构id相关参数


> 1.3.4.1 、请求信息

*   请求方式：RPC
*   请求group：workflow
*   请求地址：com.weaver.workflow.pathdef.api.rest.type.WfpTypeSetRest#createPathType

> 1.3.4.2 、入参说明

> **入参说明：**

| 参数名称   | 参数描述               | 必选 | 类型          |
| :----- | :----------------- | :- | :---------- |
| entity | 工作流类型基础信息            | 是  | WfpTypeInfoEntity对象 |
| user | 用户对象            | 是  | WeaUser对象，至少要给userid和租户key属性 |
| otherParams | 预留参数 | 否  |  扩展使用，预留参数   |
> 1.3.4.3、WfpTypeInfoEntity对象详细属性说明
```java
   /**
     * 类型id，主键唯一，传了则取传的，没传则会自动生成
     */
    private long id;

    /**
     *类型名称，必传
     */
    private String typeName;
    
    /**
     * 排序
     */
    private float orderId=0f;
    /**
     * 类型描述
     */
    private String typeDesc;
    /**
     * 类型图标
     */
    private String iconKey;
    /**
     * 分权所属机构id
     */
    private long subCompanyId;
    
    /**
     * 所属类型（团队、个人审批）
     */
    private WfpBelongType belongType;

    /**
     * 所属机构类型 0所有机构公用 1指定机构，见WfpSubCompanyType枚举
     */
    private int subCompanyType;
```
> 1.3.4.4、调用示例

```java
@Autowired
public class Test {

    @RpcReference(group = "workflow")
    private WfpTypeSetRest typeSetRest;

    public void test() {
	WeaUser user = new WeaUser();
        user.setUserId(1111L);
        user.setTenantKey("abcdsas");
        WfpTypeInfoEntity entity = new WfpTypeInfoEntity();
        //如果传了主键id，就用传的，没有传则会自动生成
        entity.setId(IdGenerator.generate());
        //类型名称
        entity.setTypeName("接口创建测试");
        //团队类型
        entity.setBelongType(WfpBelongType.COMPANY);
        WfpTypeCreateResultEntity result = typeSetRest.createPathType(entity, user,new HashMap<>());
     }
}
```
> 1.3.4.5 、返回结果说明

> WfpTypeCreateResultEntity对象属性说明
```java
   /**
     * 工作流类型id:创建失败返回-1
     */
    private long typeId;

    /**
     * 创建结果：成功true 失败false
     */
    private boolean success;
    /**
     * 创建成功或者失败的提示信息
     */
    private String msg;
```


## 2、openApi接口

> 见开发平台说明文档：https://weapp.eteams.cn/sp/opendoc/freepass/10.0.2408.01/zh_cn/949862795428020225

## 3、浏览按钮

> 见工作流模块相关浏览按钮使用文档：https://weapp.eteams.cn/ecode/playground/doc/share/view/1021774051158695936


# 二、前端口子
## 2.1 工作流设置页面JsSDK

### 2.1.1 注册工作流设置面板ComponentWillMount钩子
> 关键词：WFPathSetFrameWillMount

样例
```typescript
import { regHook } from '@weapp/utils';

async function runScript() {
  //工作流设置面板ComponentWillMount时执行
  
  //ex: const wfpJsSdk = await window.weappWorkflow.getPathSetSDK();
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);


```

### 2.1.2 获取工作流设置页面JsSDK
> getPathDefSDK: function()

> getPathDefSDK是异步方法，需要用异步方式获取
```typescript

import { regHook } from '@weapp/utils';

async function runScript() {
  
  //方式一：
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

  //方式二：
  window.weappWorkflow.getPathDefSDK().then(res => {
    const pathset_sdk=res;
  })
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);
```
### 2.1.3 注册钩子事件


目前支持的钩子类型

| 类型        | 参数描述                    |最低基线要求     |
| :--------- | :------------------------- | :----------------- |
| afterFrameInit  | 设置页面框标签页加载完成事件|  241001|
| switchTab  | 切换标签页|  待上线|


接口名称及参数说明
> registerHookEvent: function(actionname, fn)

| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| actionname | String                       | 是| 动作类型，详见上表|
| fn | Function|   是|触发事件|

样例
```typescript

import { regHook } from '@weapp/utils';

async function runScript() {
  
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

  //工作流设置页面框标签页加载完成执行
  pathset_sdk.registerHookEvent("afterFrameInit", function (params) {
      console.log("base",params);
  })
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);

```

### 2.1.4 清除钩子事件

接口名称及参数说明
> clearHookEvent: function(actionname)

| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| actionname | String                       | 是| 动作类型，详见上表|


样例
```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

  //清除标签页加载完成执行事件
  pathset_sdk.clearHookEvent("afterFrameInit");
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);

```
### 2.1.5 注册拦截事件

目前支持的拦截类型

| 类型        | 参数描述                    |最低基线要求     |
| :--------- | :------------------------- | :----------------- | 
| doSaveEvent | 保存                       | 241001|
| switchTab | 切换标签页                       | 待上线|
接口名称及参数说明
> registerInterceptEvent: function(actionname,fn)

| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| actionname | String                       | 是| 动作类型，详见上表，需结合tabKey使用：如绑定基础设置标签页下的保存事件，则actionname="doSaveEvent\|base"|
|fn|Function|是|拦截事件|

样例
```typescript

import { regHook } from '@weapp/utils';

async function runScript() {
  
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

  //绑定基础设置标签页下的保存拦截事件
  pathset_sdk.registerInterceptEvent("doSaveEvent|base", function (callback, fail, params) {
      console.log("base",params);
      callback();//要拦截保存，则不执行callback
  })
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);

```
### 2.1.6 清除拦截事件

接口名称及参数说明
> clearInterceptEvent: function(actionname)

| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| actionname | String                       | 是| 动作类型，详见上表，需结合tabKey使用：如清除绑定基础设置标签页下的保存事件，则actionname="doSaveEvent\|base"|


样例
```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

  //清除基础信息标签页下保存拦截事件
  pathset_sdk.clearInterceptEvent("doSaveEvent|base");
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);

```
### 2.1.7 获取工作流设置面板的顶部标签页数据
> clearInterceptEvent: function()

```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

  const tabs = pathset_sdk.getFrameTabs();
  console.log(tabs);
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);

```
### 2.1.8 复写工作流设置面板顶部标签页
接口名称及参数说明
> rewriteFrameTabs: function(tabs)


| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| tabs | Array                       | 是| 新的标签页数据|


样例
```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

  const tabs = pathset_sdk.getFrameTabs();
  pathset_sdk.rewriteFrameTabs(tabs.filter(item => {
      return item.id!=="advanced";//屏蔽‘高级设置’标签页
  }))
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);

```



### 2.1.9 触发面板的保存事件
>  doSaveFrame

样例
```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  setTimeout(function(){
    const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

    pathset_sdk.doSaveFrame();//执行保存事件
    
  },5000)
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);

```
### 2.1.10 获取工作间基本信息数据
接口名称及参数说明
> getBaseInfo: function()
样例
```typescript

import { regHook } from '@weapp/utils';

async function runScript() {
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();
  let baseInfo = pathset_sdk.getBaseInfo();
  console.log("baseInfo",baseInfo)
  
}

regHook('weappWorkflow', 'WFPathSetFrameWillMount', runScript);

```

### 2.1.11 禁止工作流版本切换

样例
```typescript

import { regOvProps } from '@weapp/utils';

regOvProps('weappWorkflow', 'wfppsVersionCard', props => {
  if (props.nowOpenWorkflowId === "939008455186563074") {
    props.forbidActive=true;
  }
  return props;
})


```
### 2.1.12 获取工作流基本信息数据
接口名称及参数说明
> getBaseInfo: function()

工作流基本信息数据释义

| 参数                   |  释义             |
| :----------------     |:----------------- | 
| workflowId            | 工作流id|
| workflowName          | 工作流名称|
| formId                | 当前使用的表单id|
| isFree                | 是否是自由流程 1是 0不是|
| tabKey                | 当前打开的标签页的key|
| currentBaseInfoDatas  | 工作流基础设置页签下的工作流基本信息（仅在工作流基础设置页签下才有值）|

样例
```typescript

import { regHook } from '@weapp/utils';

async function runScript() {
  const nodeset_sdk = await window.weappWorkflow.getPathNodeSDK();
  let baseInfo = nodeset_sdk.getBaseInfo();
  console.log("baseInfo",baseInfo)
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);

```
### 2.1.13 修改工作流名称
接口名称及参数说明
> changeWorkflowName: function(workflowName)

> 支持的基线版本：2505及以上版本（2503版本单独出包支持过）

| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| workflowName | string                       | 是| 新的工作流名称|

```typescript
 const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

 pathset_sdk.changeWorkflowName("新的工作流名称");
```


### 2.1.14 修改工作流基本信息（主要用于扩展基本信息）
接口名称及参数说明
> updateDatas4BaseCard: function(obj)


| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| obj | Object                       | 是| 需要扩展的对象|

```typescript
 const pathset_sdk = await window.weappWorkflow.getPathDefSDK();

 pathset_sdk.updateDatas4BaseCard({customKey:"1"});
```

## 2.2 工作流节点设置页面JsSDK

### 2.2.1 注册工作流节点设置面板ComponentWillMount钩子
> 关键词：WFPathNodeFrameWillMount

样例
```typescript
import { regHook } from '@weapp/utils';

async function runScript() {
  //工作流节点设置面板ComponentWillMount时执行
  
  //ex: const wfpnJsSdk = await window.weappWorkflow.getPathNodeSDK();
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);


```

### 2.2.2 获取工作流节点设置页面JsSDK
> getPathNodeSDK: function()

> getPathNodeSDK是异步方法，需要用异步方式获取
```typescript

import { regHook } from '@weapp/utils';

async function runScript() {
  
  //方式一：
  const nodeset_sdk = await window.weappWorkflow.getPathNodeSDK();

  //方式二：
  window.weappWorkflow.getPathNodeSDK().then(res => {
    const nodeset_sdk=res;
  })
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);
```
### 2.2.3 注册钩子事件


目前支持的钩子类型

| 类型        | 参数描述                    |最低基线要求     |
| :--------- | :------------------------- | :----------------- |
| afterFrameInit  | 设置页面框标签页加载完成事件|  241001|
| switchTab  | 切换标签页|  待上线|


接口名称及参数说明
> registerHookEvent: function(actionname, fn)

| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| actionname | String                       | 是| 动作类型，详见上表|
| fn | Function|   是|触发事件|

样例
```typescript

import { regHook } from '@weapp/utils';

async function runScript() {
  
  const nodeset_sdk = await window.weappWorkflow.getPathNodeSDK();

  //工作流节点设置页面框标签页加载完成执行
  nodeset_sdk.registerHookEvent("afterFrameInit", function (params) {
      console.log("base",params);
  })
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);

```

### 2.2.4 清除钩子事件

接口名称及参数说明
> clearHookEvent: function(actionname)

| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| actionname | String                       | 是| 动作类型，详见上表|


样例
```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  const nodeset_sdk = await window.weappWorkflow.getPathNodeSDK();

  //清除标签页加载完成执行事件
  nodeset_sdk.clearHookEvent("afterFrameInit");
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);

```
### 2.2.5 注册拦截事件

目前支持的拦截类型

| 类型        | 参数描述                    |最低基线要求     |
| :--------- | :------------------------- | :----------------- | 
| doSaveEvent | 保存                       | 241001|
| switchTab | 切换标签页                       | 待上线|
接口名称及参数说明
> registerInterceptEvent: function(actionname,fn)

| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| actionname | String                       | 是| 动作类型，详见上表，需结合tabKey使用：如绑定基础设置标签页下的保存事件，则actionname="doSaveEvent\|base"|
|fn|Function|是|拦截事件|

样例
```typescript

import { regHook } from '@weapp/utils';

async function runScript() {
  
  const nodeset_sdk = await window.weappWorkflow.getPathNodeSDK();

  //绑定基础设置标签页下的保存拦截事件
  nodeset_sdk.registerInterceptEvent("doSaveEvent|base", function (callback, fail, params) {
      console.log("base",params);
      callback();//要拦截保存，则不执行callback
  })
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);

```
### 2.2.6 清除拦截事件

接口名称及参数说明
> clearInterceptEvent: function(actionname)

| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| actionname | String                       | 是| 动作类型，详见上表，需结合tabKey使用：如清除绑定基础设置标签页下的保存事件，则actionname="doSaveEvent\|base"|


样例
```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  const nodeset_sdk = await window.weappWorkflow.getPathNodeSDK();

  //清除基础信息标签页下保存拦截事件
  nodeset_sdk.clearInterceptEvent("doSaveEvent|base");
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);

```
### 2.2.7 获取工作流节点设置面板的顶部标签页数据
> clearInterceptEvent: function()

```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  const nodeset_sdk = await window.weappWorkflow.getPathNodeSDK();

  const tabs = nodeset_sdk.getFrameTabs();
  console.log(tabs);
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);

```
### 2.2.8 复写工作流节点设置面板顶部标签页
接口名称及参数说明
> rewriteFrameTabs: function(tabs)


| 参数        | 参数类型                    |必须     |  说明 |
| :--------- | :------------------------- | :----------------- | :----------------- | 
| tabs | Array                       | 是| 新的标签页数据|


样例
```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  const nodeset_sdk = await window.weappWorkflow.getPathNodeSDK();

  const tabs = nodeset_sdk.getFrameTabs();
  nodeset_sdk.rewriteFrameTabs(tabs.filter(item => {
      return item.id!=="flow";//屏蔽‘流转设置’标签页
  }))
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);

```



### 2.2.9 触发工作流节点设置面板的保存事件
>  doSaveFrame

样例
```typescript


import { regHook } from '@weapp/utils';

async function runScript() {
  
  setTimeout(function(){
    const nodeset_sdk = await window.weappWorkflow.getPathNodeSDK();

    nodeset_sdk.doSaveFrame();//执行保存事件
    
  },5000)
  
}

regHook('weappWorkflow', 'WFPathNodeFrameWillMount', runScript);

```

## 2.3 	组件复写
### 2.3.1 复写工作流名称组件
>涉及的组件 WfppsBaseInfo

示例效果

![](${appMdRes}/1747190787-image.png)
复写示例
```typescript
import { regOvProps } from '@weapp/utils';

async function doClick() {
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();
  const { changeWorkflowName } = pathset_sdk;
  changeWorkflowName("新名称");
}


function customRender(coms) {
  const {Button} = window.weappUi;
  return <>
    {coms}
    <Button onClick={doClick} type='primary'>扩展的按钮</Button>
  </>;
}



regOvProps('weappWorkflow', 'WfppsBaseInfo', (props) => {
  props.customRenderItemByKey = {
    "workflowName": customRender,
  }
  return props;
}, 0);
```
### 2.3.2 复写工作流类型图标组件
参考文档4.7
## 2.4 	组件参数复写
### 2.4.1 复写工作流管理设置页面页面
组件名称 
> WfppsMainContent

组件描述：
> 工作流设置面板组件

复写示例
```typescript
import { regOvProps } from '@weapp/utils';
async function runScript() {
  const wfpJsSdk = await window.weappWorkflow.getPathDefSDK();
  //拦截基础设置标签页下保存事件
  wfpJsSdk.registerInterceptEvent("doSaveEvent|base", function (callback, fail, params) {
    console.log("base-params", params)
    callback()
  })
  //拦截功能设置标签页下保存事件
  wfpJsSdk.registerInterceptEvent("doSaveEvent|function", function (callback, fail, params) {
    console.log("function-params", params)
    callback()
  })
}
regOvProps('weappWorkflow', 'WfppsMainContent', props => {
  if (!props.wfppsFrameStore.workflowId) {
    runScript()
  }
  return props;
})


```

## 2.5、工作流列表通过url控制界面显示内容
> 工作流列表单页地址：/sp/workflow/workflow_setting/pathdef/list/company

![](${appMdRes}/1736474289-image.png)
### 2.5.1控制工作流类型左侧树的显示隐藏
| 参数        | 参数类型                     |  说明 |
| :--------- | :------------------------- | :----------------- | 
| noTypeTree | 0/1                       | 默认要渲染工作流类型左侧树，url上设置1则默认不渲染|
| defaultShowTypeTree | 0/1              | 默认不展开工作流类型左侧树,url上设置1则默认展开|

示例：
- /sp/workflow/workflow_setting/pathdef/list/company?noTypeTree=1

![](${appMdRes}/1736474356-image.png)
- /sp/workflow/workflow_setting/pathdef/list/company?defaultShowTypeTree=1

![](${appMdRes}/1736474322-image.png)
# 三、常用表说明/Sql
> 比如工作流类型、工作流、工作流节点、出口，表名和关联关系如下

> 二开不要直接写sql，优先通过接口调用，没有接口的评估开放；此处仅列举常用表、sql做了解

| 表名        | 表说明        | 重要外键说明                    | 相关sql                                                     |
| :-------- | :--------- | :------------------------ | :-------------------------------------------------------- |
| wfp\_type | 工作流类型基础信息表 |                           | 根据id查询工作流类型：select \* from wfp\_type where id=?           |
| wfp\_base | 工作流基础信息表   | workflowtype=wfp\_type.id | 根据id查询工作流：select \* from wfp\_base where id=?               |
| wfp\_node | 工作流节点基础信息表 | workflowid=wfp\_base.id   | 查询某个工作流下所有节点：select \* from wfp\_node where workflowid=？  |
| wfp\_link | 工作流出口基础信息表 | workflowid=wfp\_base.id   | 查询某个工作流下所有节出口：select \* from wfp\_link where workflowid=？ |

> 核心表的完整表结构见文档：https://weapp.eteams.cn/ecode/playground/doc/share/view/1009989752031092737


# 四、二开场景案例
## 4.1、工作流管理扩展页签
```
开发复写组件：Menu、MenuContent
复写组件关键词：bindKey=‘wf_pathset_main’
```
### 4.1.1、效果展示：
	
![](${appMdRes}/1727349477-image.png)
### 4.1.2、示例代码
entry.js
```typescript
import { regOvProps, regOvComponent } from '@weapp/utils';
import { asyncImport } from '@weapp/ecodesdk';

const newBindKey = "wf_pathset_main";

const CustomMenuContentAsync = React.lazy(() => asyncImport('${appId}', 'index'));

regOvProps('weappUi', 'Menu', props => {
  if (props.bindKey == newBindKey) {
    let menuData = [...props.data, {
      content: "自定义页签1",
      disabled: false,
      id: "customTab1"
    }]
    props.data = menuData;
  }
  return props;
})

regOvComponent('weappUi', 'MenuContent', (Com) => {
  return React.forwardRef((props, ref) => {
    const { key, dataId, value, bindKey, weId = '' } = props;
    let isMainMenuContent = bindKey === newBindKey && key == 'custom';
    let otherParams = {};
    if (isMainMenuContent && value === 'customTab1') otherParams = { style: { display: "none" } }
    return (
      <React.Suspense fallback={() => { }}>
        <Com ref={ref} {...props} {...otherParams} />
        {
          isMainMenuContent && <>
            <div style={value === 'customTab1' ? { width: '100%', height: '100%' } : { display: 'none' }}>
              <CustomMenuContentAsync {...props} OriginCom={Com} />
            </div>
          </>
        }
      </React.Suspense>
    );
  });
});
```
index.js
```typescript
import React from 'react';

class CustMenuContent extends React.Component {
  render() {
    const { OriginCom, ...others } = this.props;
    return <div className="cust-tab-content">
        自定义内容111
      </div>
  }
}

export default CustMenuContent;


```
## 4.2、节点设置扩展页签
```
开发复写组件：Menu、MenuContent
复写组件关键词：bindKey=‘wf_nodeset_main’
```
### 4.2.1、效果展示：

![](${appMdRes}/1727349680-image.png)
### 4.2.2、示例代码
entry.js
```typescript
import { regOvProps, regOvComponent } from '@weapp/utils';
import { asyncImport } from '@weapp/ecodesdk';

const newBindKey = "wf_nodeset_main";

const CustomMenuContentAsync = React.lazy(() => asyncImport('${appId}', 'index'));

regOvProps('weappUi', 'Menu', props => {
  if (props.bindKey == newBindKey) {
    let menuData = [...props.data, {
      content: "自定义页签1",
      disabled: false,
      id: "customTab1"
    }]
    props.data = menuData;
  }
  return props;
})

regOvComponent('weappUi', 'MenuContent', (Com) => {
  return React.forwardRef((props, ref) => {
    const { key, dataId, value, bindKey, weId = '' } = props;
    let isMainMenuContent = bindKey === newBindKey && key == 'custom';
    let otherParams = {};
    if (isMainMenuContent && value === 'customTab1') otherParams = { style: { display: "none" } }
    return (
      <React.Suspense fallback={() => { }}>
        <Com ref={ref} {...props} {...otherParams} />
        {
          isMainMenuContent && <>
            <div style={value === 'customTab1' ? { width: '100%', height: '100%' } : { display: 'none' }}>
              <CustomMenuContentAsync {...props} OriginCom={Com} />
            </div>
          </>
        }
      </React.Suspense>
    );
  });
});
```
index.js
```typescript
import React from 'react';

class CustMenuContent extends React.Component {
  render() {
    const { OriginCom, ...others } = this.props;
    return <div className="cust-tab-content">
        自定义内容111
      </div>
  }
}

export default CustMenuContent;


```


## 4.3、复写工作流基本信息工作流名称控件
```
开发复写组件：WfppsBaseInfo
```
### 4.3.1、效果展示：

![](${appMdRes}/1744365426-image.png)
### 4.3.2、示例代码
entry.js
```typescript
import { regOvProps } from '@weapp/utils';

async function doClick() {
  const pathset_sdk = await window.weappWorkflow.getPathDefSDK();
  const { changeWorkflowName } = pathset_sdk;
  changeWorkflowName("新名称");
}


function customRender(coms) {
  const {Button} = window.weappUi;
  return <>
    {coms}
    <Button onClick={doClick} type='primary'>扩展的按钮</Button>
  </>;
}



regOvProps('weappWorkflow', 'WfppsBaseInfo', (props) => {
  props.customRenderItemByKey = {
    "workflowName": customRender,
  }
  return props;
}, 0);
```

## 4.4、工作流类型支持多级

### 4.4.1、效果展示

> 新建或者编辑类型时，支持选择上级类型
![](${appMdRes}/1749029675-image.png)

> 工作流类型列表支持父子关系多级显示效果
![](${appMdRes}/1749029559-image.png)

> 完整功能说明见如下文档：

[工作流类型支持多级功能说明文档](https://www.e-cology.com.cn/sp/doc/docDetail/1126552733483212826?type=IM_View&_isEm=1&_emUid=6264065512356446344&_emCid=874152414695915520&authModule=im&weappAuthStr=eyJtc2dpZCI6IjE3NDg1ODg2NzQxNjAyNTgxODQiLCJmbGFnIjowLCJ1c2VyIjp7ImNpZCI6Ijg3NDE1MjQxNDY5NTkxNTUyMCIsInVpZCI6IjYyNjQwNjU1MTIzNTY0NDYzNDQifX0=)

### 4.4.2、开启方式

> nacos配置文件中，配置指定的租户开启工作流类型多级功能，配置内容如下：

~~~
#开启了工作流类型支持多级的租户key,多个逗号分割
#{"type":"env","value":"none"}
weaver.workflow.type.multiLevelTenantKey=
~~~
注意不要重复配置，改之前搜一下，如果此配置已经存在，直接改值加上租户key即可，不需要再重复复制一份，此配置不存在的才复制整段配置
> 最终效果如下图：

![](${appMdRes}/1749030396-image.png)

**注意:**

> 1、这2个配置文件：weaver-workflow-pathdef-service.properties和weaver-workflow-list-service.properties，都需要配置

> 2、配置后重启流程的服务

> 3、如何修改nacos配置，可以参考如下文档，第七节内容： [nacos配置文件如何修改](https://weapp.eteams.cn/ecode/playground/doc/share/view/1090131883071807489)


## 4.5、工作流审核发布支持二开

### 4.5.1 支持创建任意流程，且具备审核发布的能力

文档链接：[审核发布支持二开对接说明文档](https://weapp.eteams.cn/ecode/playground/doc/share/view/1146432195604078592)

### 4.5.2 修改工作流任意配置后需审核后生效

文档链接：[修改工作流任意配置后需审核后生效二开对接说明文档](https://weapp.eteams.cn/ecode/playground/doc/share/view/1146429223629316097)

## 4.6、新建工作流、新建节点，支持ecode二开埋点调用

- 最低支持基线：**2603基线**

- 新建工作流或者新建节点完成以后，标准预留口子，支持调用ecode二开的自定义钩子类，钩子入参包含工作流id、节点id等信息
   
- 可用于给新建的工作流或者节点，初始化一些配置项默认值。

### 4.6.1 新建工作流二开埋点钩子对接说明

> 编写二开钩子实现类，demo如下：

~~~
@Slf4j
@WeaHookReg(code = "WORKFLOW_PATHDEF_CREATE_PATH_001", order = 0)
public class WeaHookRegDemo extends RegHookEvent {
    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取钩子入参，入参包含新建的工作流id等信息
        Map<String, Object> params = request.getParams();
        
        //todo 这里开始写自定义的代码
		
        
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //todo
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }
}

~~~

> 钩子入参params值详细说明
~~~
Map<String, Object> params = new HashMap<>();
//当前用户id
params.put("userId", user.getUserId() + "");
//当前租户key
params.put("tenantKey", user.getTenantKey());
//新建的工作流信息，具体值见com.weaver.workflow.common.entity.pathdef.path.base.WfpBaseInfoEntity类
params.put("baseInfoEntity", wfpBaseInfoEntity);
//工作流id
params.put("workflowId", wfpBaseInfoEntity.getId()+"");
//工作流关联的表单id
params.put("formId", formId + "");
//工作流关联的表单类型，具体值见com.weaver.workflow.common.constant.formdef.WfpRelateFormType枚举
params.put("formType", wfpRelateFormType.getCode());
~~~


### 4.6.2 新建节点二开埋点钩子对接说明

> 编写二开钩子实现类，demo如下：

~~~
@Slf4j
@WeaHookReg(code = "WORKFLOW_PATHDEF_CREATE_NODE_001", order = 0)
public class WeaHookRegDemo extends RegHookEvent {
    @Override
    public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //获取钩子入参，入参包含新建的工作流id等信息
        Map<String, Object> params = request.getParams();
        
        //todo 这里开始写自定义的代码
		
        
    }

    @Override
    public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
        //todo
        //自定义二开代码异常回滚逻辑
        log.info("执行事件回滚机制 => {}, {}", DateUtil.now(), appInfo.getAppName());
    }
}

~~~

> 钩子入参params值详细说明
~~~
Map<String, Object> params = new HashMap<>();
//当前用户id
params.put("userId", user.getUserId() + "");
//当前租户key
params.put("tenantKey", user.getTenantKey());
//新建的节点信息，具体值见com.weaver.workflow.common.entity.pathdef.pathnode.base.WfpNodeBaseEntity类
params.put("nodeBaseEntity", nodeBaseEntity);
//节点id
params.put("nodeId", nodeBaseEntity.getId());
~~~
## 4.7、工作流类型图标更换
> 组件名称：WfpPathTypeIcon

> 最低基线要求：260501

更换图标生效的范围
| 生效范围        | 
| :-------- |
| 移动端/pc端新建流程列表 |
| 移动端/pc端待办/已办/我的请求/全部流程列表|
| 移动端/pc端工作流路径列表|
| pc端类型设置列表、批量删除列表|

### 4.7.1 效果展示

更改前

![](${appMdRes}/1775617391-image.png)
更改后

![](${appMdRes}/1775617423-image.png)

### 4.7.2 代码示例

entry.js
``` typescript
import { regOvComponent } from '@weapp/utils';
import { asyncImport } from '@weapp/ecodesdk';


const NewWfTypeIcon = React.lazy(() => asyncImport('${appId}', 'NewWfTypeIcon'));
const overwriteFunction = (Com) => {
  return React.forwardRef((props, ref) => {
    return (
      <React.Suspense fallback={() => {}}>
        <NewWfTypeIcon ref={ref} {...props} OriginCom={Com} />
      </React.Suspense>
    )
  });
}
regOvComponent('weappWorkflow', 'WfpPathTypeIcon', overwriteFunction, 0)

```

NewWfTypeIcon.js
``` typescript
import { AppIcon } from '@weapp/ui';
import { appInfo } from '@weapp/utils';
export default class NewWfTypeIcon extends React.Component<any>{


  isMobile = () => {
    const root = appInfo('@weapp/workflow').publicUrl || "";
    return window.location.pathname.indexOf(root + '/mobile') === 0;
  }

  render() {
    const { OriginCom, typeId } = this.props;
    if (typeId === '1116156318384840720' || typeId === '1250068098689654784') {
      console.log("this.porps", this.porps)
      return <AppIcon
        {...this.props}
        iconProps={
          {
            ...(this.props?.iconProps ? this.props.iconProps : {}),
            name: 'Icon-adaptive',//图标名称 所有图标在此处查询 https://weapp.eteams.cn/iconfont/resource/icon
          }
        } />
    } else {
      return <OriginCom {...this.props} />;
    }
  }
}

```