# 流程列表后端二开口子

## 一、后端接口相关
> 地址：[点击查看](https://weapp.eteams.cn/ecode/playground/doc/share/view/1222505043058999297)


## 二、配置项
> 非单体部署客户，需要到nacos修改配置<br>
> 单体部署客户，需要到/e10服务部署目录/webapps/ROOT/WEB-INF/classes/weaver/config/config-center目录修改，修改完需要重启服务

### 2.1、关联流程浏览按钮相关配置

#### 2.1.1、配置指定表单下关联流程浏览按钮，浏览按钮弹窗内流程名称按照列表标题设置展示，回显时显示原始标题

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.workflow.list.onlyNeedNameBrowserFormIds
- 配置项value说明：配置需要走池逻辑的表单id，多个以英文逗号拼接
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2305.01
- 配置示例：
> 
```properties
weaver.workflow.list.onlyNeedNameBrowserFormIds=972133699836125186,972133699836125186
```

### 2.2、流程列表标题相关配置

#### 2.2.1、配置流程列表标题历史数据重算功能时间限制

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.workflow.list.initTimeRange
- 配置项value说明：配置时间段，单位是小时分钟（24小时制），此配置跨天，例如配置值为20:00,08:00时，表示晚上8点到第二天早上8点期间，都可以操作流程列表标题历史数据重算功能
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2311.01
- 配置示例：
> 
```properties
weaver.workflow.list.initTimeRange=20:00,08:00
```

#### 2.2.2、指定数字、金额、部门、分部控件在列表标题中显示原值（数字控件不显示百分比/千分比、金额控件不显示大写/千分位、部门/分部控件不显示组织全路径）

- 配置文件名称：weaver-workflow-list-service.properties、weaver-workflow-core-service.properties（两个配置文件都要配置才会生效）
- 配置项名称：weaver.workflow.list.showOriginValueFieldIds
- 配置项value说明：配置相关表单控件的字段id，多个以英文逗号拼接
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2407.01
- 配置示例：
> 
```properties
weaver.workflow.list.showOriginValueFieldIds=1016556503658348546,1016556503658348547,1016556503658348548
```

#### 2.2.3、数字控件在列表标题中是否显示 千分比 百分比

- 配置文件名称：weaver-workflow-list-service.properties、weaver-workflow-core-service.properties（两个配置文件都要配置才会生效）
- 配置项名称：weaver.workflow.list.needShowNumberType
- 配置项value说明：配置为true或false，默认值为true，表示数字控件在列表标题中显示 千分比 百分比
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2407.01
- 配置示例：
> 
```properties
weaver.workflow.list.needShowNumberType=true
```

#### 2.2.4、金额控件在列表标题中是否显示大写

- 配置文件名称：weaver-workflow-list-service.properties、weaver-workflow-core-service.properties（两个配置文件都要配置才会生效）
- 配置项名称：weaver.workflow.list.needShowCapital
- 配置项value说明：配置为true或false，默认值为true，表示金额控件在列表标题中显示大写
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2407.01
- 配置示例：
> 
```properties
weaver.workflow.list.needShowCapital=true
```

#### 2.2.5、金额控件在列表标题中是否显示 千分位

- 配置文件名称：weaver-workflow-list-service.properties、weaver-workflow-core-service.properties（两个配置文件都要配置才会生效）
- 配置项名称：weaver.workflow.list.needShowDelimiter
- 配置项value说明：配置为true或false，默认值为true，表示金额控件在列表标题中显示 千分位
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2407.01
- 配置示例：
> 
```properties
weaver.workflow.list.needShowDelimiter=true
```

#### 2.2.6、部门、分部控件在列表标题中是否显示 组织全路径

- 配置文件名称：weaver-workflow-list-service.properties、weaver-workflow-core-service.properties（两个配置文件都要配置才会生效）
- 配置项名称：weaver.workflow.list.needShowAllDepartmentPath
- 配置项value说明：配置为true或false，默认值为true，表示部门、分部控件在列表标题中显示 组织全路径
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2407.01
- 配置示例：
> 
```properties
weaver.workflow.list.needShowAllDepartmentPath=true
```

#### 2.2.7、字段无值时需要隐藏字段标签的workflowid

- 配置文件名称：weaver-workflow-list-service.properties、weaver-workflow-core-service.properties（两个配置文件都要配置才会生效）
- 配置项名称：weaver.workflow.list.reqNameEmptyFieldsParseLabel
- 配置项value说明：字段无值时需要隐藏字段标签的workflowid  多个workflowid逗号分隔，配置为-1代表全部工作流
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2407.01
- 配置示例：
> 
```properties
weaver.workflow.list.reqNameEmptyFieldsParseLabel=-1
```

#### 2.2.8、屏蔽标题刷新的workflowid集合

- 配置文件名称：weaver-workflow-list-service.properties、weaver-workflow-core-service.properties（两个配置文件都要配置才会生效）
- 配置项名称：weaver.workflow.list.shieldingParseRequestNameWfIds
- 配置项value说明：屏蔽标题刷新的workflowid集合  多个workflowid逗号分隔
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2308.01
- 配置示例：
> 
```properties
weaver.workflow.list.shieldingParseRequestNameWfIds=1
```
  
### 2.3、流程列表显示相关配置

#### 2.3.1、流程列表支持配置控制屏蔽行操作菜单

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.workflow.list.removeRowActions
- 配置项value说明：具体值见下方【行操作菜单标识参考】，屏蔽多个菜单的时候，菜单标识用英文逗号隔开
- <font color="red">配置注意事项：不允许全部屏蔽，请至少放出一个行操作，避免前台因为没有行操作而显示异常</font>
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2310.02
- 配置示例：
> 
```properties
#屏蔽列表行操作“标记为已读”，“转发”菜单
weaver.workflow.list.removeRowActions=markRead,forward
```
> 行操作菜单标识枚举参考：
> 
```js
    MARK_READ("标记为已读","markRead",58843L),
    FORWARD("转发","forward",57697L),
    MARKTAG("标记标签", "markTag", 101559L),
    ATTENTION("关注", "attention",58842L),
    CANCEL_ATTENTION("取消关注","cancelAttention",58841L),
    PRINT("打印","print",58835L),
    SHARE("共享","share",58834L),
    FLOW_LOG("表单日志", "flowLog",58833L),
    URGE("催办", "urge",64892L),
    SUPERVISE("督办", "supervise",58832L),
    RECEIVE("恢复", "receive",58831L),
    DELETE("删除" ,"delete",53465L),
    INTERVENE("干预", "intervene", 57858L),
    INTERVENE_LOG("干预日志", "interveneLog", 57882L),
    STOP("暂停", "stop", 65315L),
    CANCEL("撤销", "cancel", 59804L),
    RESTART("启用", "restart", 107L),
    FORCE_DRAW_BACK("强制收回", "forceDrawBack", 58981L),
    FORCE_ARCHIVING("强制结束", "forceArchiving", 100163L),
    MONITOR_TYPE_EDIT("编辑", "monitorTypeEdit", 53461L),
    MONITOR_TYPE_DELETE("删除", "monitorTypeDelete", 53465L),
    DELETE_NORMAL("删除","deleteNormal",53465L),
    MAKE_TODOITEM("设为待办事项", "makeTodoItem", 94751L),
    FORM_LOG("表单日志", "formLog", 58833L),
    SAVE_TODOC("存为文档", "savetodoc", 105490L),
    PRINT_LOG("打印日志", "printLog", 65326L),
    MONITOR_SET_EDIT("编辑", "edit", 53461L),
    MONITOR_SET_DELETE("删除", "delete", 53465L),
    NO_DISTURB_INTO("移入免打扰", "noDistrubInto", 150864L),
    NO_DISTURB_OUT("移至待办", "noDistrubOut", 150865L),
    ADD_SIGN_ASSIST("代录意见", "addSignAssist", 156845L),
    EDIT_SIGN("修改意见", "editSign", 156846L),
    VIEW_EDIT_SIGN_LOG("意见调整日志", "viewEditSignLog", 156847L),
    TRIGGER_SUB_REQ("触发子流程", "triggerSubReq", 65944L),
    ADD_OPERATOR("加审", "addOperator", 106837L),
    MINUS_OPERATOR("减审", "minusOperator", 140016L),
    EDIT_FORM_DATA("修改表单内容","editFormData",244974L),
    ;
  ```
> 
#### 2.3.2、流程列表不显示状态为停用状态工作流下的流程数据

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.workflow.list.filterInValidWorkflow
- 配置项value说明：false:列表上正常显示停用状态工作流下的数据  true:列表上不显示停用状态工作流下的数据
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.25.08（2508：weaver-workflow-list-1.72.0-hotfix10，2509：1.73.0-hotfix8）
- 配置示例：
> 
```properties
weaver.workflow.list.filterInValidWorkflow=true
```

#### 2.3.3、移动端如何显示系统名称及所属工作流名称

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.workflow.list.showWfAndSysName4Mobile
- 配置项value说明：false:移动端列表不显示系统名称及所属工作流名称  true:移动端列表显示系统名称及所属工作流名称
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.25.01
- 配置示例：
> 
```properties
weaver.workflow.list.showWfAndSysName4Mobile=true
```


#### 2.3.4、流程列表数据源，如何统计次账号数据（注意：只能用于数量统计，如果是流程显示，请使用流程列表组件替代）

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.workflow.list.needBelongTodo4Ds
- 配置项value说明：false:流程列表数据源不统计次账号数据  true:流程列表数据源统计次账号数据
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.25.09
- 配置示例：
> 
```properties
weaver.workflow.list.needBelongTodo4Ds=true
```

#### 2.3.5、流程列表数据源，如何统计统一待办数据（注意：只能用于数量统计，如果是流程显示，请使用流程列表组件替代）

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.workflow.list.needIutData4Ds
- 配置项value说明：false:流程列表数据源不统计统一待办数据  true:流程列表数据源统计统一待办数据
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.25.09
- 配置示例：
> 
```properties
weaver.workflow.list.needIutData4Ds=true
```

#### 2.3.6、待办、已办等列表（全部列表除外），自定义查询默认不显示表单字段，如果需要显示，需要手动从自定义列设置上放开

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.workflow.list.defaultHideFormField
- 配置项value说明：false:自定义查询表单字段默认显示出来  true:自定义查询表单字段默认不显示，需要手动放开
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.25.11（weaver-workflow-list-1.75.0-hotfix1）
- 配置示例：
> 
```properties
weaver.workflow.list.defaultHideFormField=true
```
#### 2.3.7、流程列表组件-待办流程，不显示免打扰数据

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.workflow.list.portalShowDisturb
- 配置项value说明：false:不显示免打扰数据  true:显示免打扰数据
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.26.04
- 配置示例：
> 
```properties
weaver.workflow.list.portalShowDisturb=true
```
  
### 2.4、统一待办推送相关

#### 2.4.1、统一待办开启非公开数据的推送

- 配置文件名称：weaver-workflow-list-service.properties、weaver-workflow-core-service.properties
- 配置项名称：weaver.workflow.list.sendIutMsgFilterBySecLevel
- 配置项value说明：true:只推送公开密级的流程 false:密级条件不再判断，推送所有密级的流程
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2411.01
- 配置示例：
> 
```properties
#统一待办推送是否根据密级过滤数据
weaver.workflow.list.sendIutMsgFilterBySecLevel=false
```

#### 2.4.2、统一待办发起节点待办（草稿）是否推送

- 配置文件名称：weaver-workflow-core-service.properties
- 配置项名称：weaver.workflow.list.disableIutCreateEndDataSend
- 配置项value说明：true:流程创建产生的发起人待办数据不推统一待办 false:正常推送
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2603.01
- 配置示例：
> 
```properties
#统一待办推送是否推送发起节点发起人的待办
weaver.workflow.list.disableIutCreateEndDataSend=true
```

### 2.5、移动端工作流程应用相关

#### 2.5.1、移动端统计菜单如何关闭

- 配置文件名称：weaver-workflow-list-service.properties
- 配置项名称：weaver.report.newHiddenMAppFormReport、weaver.workflow.list.mobileBottomDspFlag
- 配置项value说明：true:移动端底部显示统计菜单 false:正常显示（标准效果）
- 是否需要重启（非单体）：否
- 最低支持版本：10.0.2604.01
- 配置示例：
> 
```properties
#移动端底部不显示统计菜单
weaver.report.newHiddenMAppFormReport=true
#移动端底部需要显示的菜单类型（agent:委托菜单、msupervise:督办、monitor:监控）
weaver.workflow.list.mobileBottomDspFlag=agent
```
#### 受控功能位置:

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


## 三、后端埋点

## 前提
```java
口子生效前提：
nacos上找到weaver-workflow-list-services.properties配置文件(如果是单体：部署根目录/webapps/ROOT/WEB-INF/classes/weaver/config/config-center/weaver-workflow-list-service.properties) 检查下是否有这个配置：
如果有，检查下是否是true，如果没有直接加到最后
weaver.workflow.list.openListSecondHook=true
```

## 3.1、标准流程列表、标准流程列表组件、rpc接口（上述第一点中的rpc接口）接口支持拼接自定义查询条件
> 标准流程列表入口、标准eb设计器里面流程列表组件入口、rpc接口的待办、已办、我发起的等列表，在原有列表查询条件基础之上，支持拼接远程钩子返回的二开自定义查询条件。

### 3.1.1、支持基线 
  250201基线后支持

### 3.1.2、event事件说明
> **标准流程列表：**
  
| 事件名称 | 说明 | 入参类型 |
| --- | --- | --- |
| wflQueryData | 标准流程列表，分页数据接口 | com.weaver.workflow.common.dto.list.hook.remote.params.WflQueryHookParams4Data |
| wflQueryTotal | 标准流程列表，总数接口 | com.weaver.workflow.common.dto.list.hook.remote.params.WflQueryRemoteHookParams|
| wflQueryTree | 标准流程列表，左侧树接口 | com.weaver.workflow.common.dto.list.hook.remote.params.WflQueryRemoteHookParams|
| wflQueryCount | 标准流程列表，左侧树数量及tab数量接口 | com.weaver.workflow.common.dto.list.hook.remote.params.WflQueryRemoteHookParams|
| wflQueryExist | 标准流程列表，校验列表是否有数据接口 | com.weaver.workflow.common.dto.list.hook.remote.params.WflQueryRemoteHookParams|

  

> **流程列表组件：**

| 事件名称 | 说明 | 入参类型 |
| --- | --- | --- |
| wflPortalData | 流程列表组件，分页数据接口 | com.weaver.workflow.common.dto.list.hook.remote.params.portal.WflPortalRemoteHookParams| 
| wflPortalTotal | 流程列表组件，总数接口 | com.weaver.workflow.common.dto.list.hook.remote.params.portal.WflPortalRemoteHookParams |
  
> **RPC接口(2508基线后支持)：**

| 事件名称 | 说明 | 入参类型 |
| --- | --- | --- |
| wflRpcData | 获取列表数据rpc口子SQL条件埋点-data | com.weaver.workflow.common.dto.list.hook.remote.params.WflQueryRemoteHookParams|
| wflRpcTotal | 获取列表数据rpc口子SQL条件埋点-total | com.weaver.workflow.common.dto.list.hook.remote.params.WflQueryRemoteHookParams|
  

### 3.1.3、入参说明
> **标准流程列表：**
  
| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| dimension | String | 列表维度，标记是待办、已办等类型，对应枚举com.weaver.workflow.common.constant.list.requestlist.RequestListDimensionEnum的dimension属性 |
| userId | Long | 当前登录用户ID |
| listParamVoEntity | com.weaver.workflow.common.entity.list.requestlist.RequestListParamVoEntity | 标准流程列表统一入参，里面包含很多参数，需要的时候可以直接咨询  |

> **流程列表组件：**
  
| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| dimension | String | 列表维度，标记是待办、已办等类型，对应枚举com.weaver.workflow.common.constant.list.requestlist.RequestListDimensionEnum的dimension属性|
| userId | Long | 当前登录用户ID |
| portalListParam | com.weaver.workflow.common.entity.list.portal.PortalRequestListParamEntity | 流程列表组件统一入参，里面包含很多参数，需要的时候可以直接咨询  |
  
> **RPC接口：**
  
| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| dimension | String | 列表维度，标记是待办、已办等类型，对应枚举com.weaver.workflow.common.constant.list.requestlist.RequestListDimensionEnum的dimension属性|
| userId | Long | 当前登录用户ID |
| listDataParam | com.weaver.workflow.common.entity.list.api.RequestListParamApiEntity | rpc获取列表数据接口入参  |
| listCountParam | com.weaver.workflow.common.entity.list.portal.PortalRequestListParamEntity | rpc获取列表计数接口入参  |
| conditionEntity | com.weaver.workflow.common.entity.list.api.RequestListConditionApiEntity | rpc接口搜索条件入参  |

### 3.1.4、钩子返回值说明
> **返回值为map，放入以下两个key**

| 属性名 | 类型 | 说明 |
| --- | --- | --- |
| secondSqlWhere | String | 二开自定义SQL条件片段，该片段最终会拼接在标准查询SQL上|
| secondSqlWhere4Iut | String | 二开自定义SQL条件片段，该片段最终会拼接在标准查询SQL上（统一待办数据，开启统一待办中心功能才需处理该属性） |
| quickSqlWhere（2509基线后支持） | Map<String, Object> | 快捷搜索SQL条件判断，key是快捷搜出条件标识，value为具体的SQLwhere片段 |
| quickSqlWhere4Iut（2509基线后支持） | Map<String, Object> | （统一待办部分）快捷搜索SQL条件判断，key是快捷搜出条件标识，value为具体的SQLwhere片段 |

### 3.1.5、示例代码
```java
package com.weaver.seconddev.workflow.list;

import com.alibaba.fastjson.JSONObject;
import com.weaver.loom.api.annotation.RegHook;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
import com.weaver.loom.context.domain.WeaHookResponse;
import com.weaver.loom.context.register.AbstractRegHookEvent;
import com.weaver.loom.context.register.RegHookEvent;
import com.weaver.workflow.common.constant.list.listbutton.RequestListInitButtonEnum;
import com.weaver.workflow.common.dto.list.hook.remote.params.WflQueryHookParams4Data;
import com.weaver.workflow.common.dto.list.hook.remote.res.WflQueryRemoteHookRes4Data;
import com.weaver.workflow.common.util.DataTransUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * 流程列表埋点demo：对应标准流程列表分页数据接口
 *
 * @author: zhhy
 * @created: 2025/01/13 16:40
 */
@RegHook(module = "workflow", event = "wflQueryData", order = 0)
public class WeaWflListQueryHookDemo extends AbstractRegHookEvent {

    private static final Logger log = LoggerFactory.getLogger(WeaWflListQueryHookDemo.class);


    @Override
    public Object handle(Object[] args) throws Exception {
        log.info("args:{}", JSONObject.toJSONString(args));
        WflQueryHookParams4Data params4Data = (WflQueryHookParams4Data) args[0]; //此处对应7.1.1事件说明的参数类型，不同事件强转成不同的类型
        //返回值，此处用的具体对象，实际开发的时候使用map即可
				Map<String, Object> res = new HashMap<>();
        if(params4Data != null){
            switch (DataTransUtil.null2String(params4Data.getDimension())){
                case "todo":
                    res.put("secondSqlWhere", " viewdatetime is null "); //待办只显示未读数据
                    res.put("secondSqlWhere4Iut", " viewtype = 1 ");  //待办异构系统只显示未读数据
                    break;
                case "done":
		    res.put("secondSqlWhere", " operatedatetime > '2025-01-01 00:00:00' ");  //已办显示操作时间 25年1月1号后的数据
                    res.put("secondSqlWhere4Iut", " operatedatetime > '2025-01-01 00:00:00' "); //已办显示操作时间 25年1月1号后的数据
                    break;
            }
        }
          //快捷搜索支持二开口子，2509基线后支持，只涉及列表数据和总数接口（待办、已办、我发起的、全部列表支持）
        if(!CollectionUtils.isEmpty(wflQueryHookParams4Data.getListParamVoEntity().getSearchParams().getQuickSearchDatas())){
            Map<String, Object> quickSearchDatas = new HashMap<>();
            quickSearchDatas.put("request_logs", " t1.requestid in (select requestid  from wfc_requestlog wrl where remark like '%1%' )");

            Map<String, Object> quickSearchDatasIut = new HashMap<>();
            quickSearchDatasIut.put("request_logs", " iutdata.request_id in (11111111111111)");

            resData.put("quickSqlWhere", quickSearchDatas);
            resData.put("quickSqlWhere4Iut", quickSearchDatasIut);
        }
        log.info("res:{}", JSONObject.toJSONString(res));
        return res;
    }
}

```
## 3.2、标准流程列表，获取列表数据rpc接口支持返回自定义内容
> 标准流程列表入口、及上述1.1接口，在原有列表查询条件基础之上，支持拼接远程钩子返回的二开自定义查询条件。
### 3.2.1、支持基线 
	2508基线后支持

### 3.2.2、event事件说明
> **标准流程列表：**
  
| 事件名称 | 说明 | 入参类型 |
| --- | --- | --- |
| wflCusResData | 流程列表自定义返回二开内容-data接口 | com.weaver.workflow.common.dto.list.hook.remote.params.WflGetCusResParams |
| wflRpcResData | 获取列表数据rpc口子自定义返回数据埋点 | com.weaver.workflow.common.dto.list.hook.remote.params.WflGetCusResParams|
  
### 3.2.3、入参说明
| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| originListData（不推荐参考） | com.weaver.workflow.common.dto.list.hook.remote.params.SimpleListData | 包含当前列表查询涉及的requestid |
| completeListData（2602基线后支持）| Map | 数据库查询出来的全量原始值 |
| listDataParam | 强转map即可 | 接口原始参数 |
| conditionEntity | 强转map即可 | 接口原始高级搜索参数 |

### 3.2.4、钩子返回值说明
	返回值Map<String, Map<String, Object>>，key是String类型的requestId，value是Map<String,Object>，value值最终会放到接口返回值里面一起返回给前台
  
## 3.3、标准流程列表组件&标准流程列表：待办、已办、我发起的支持关联自定义表，进行自定义排序

### 3.3.1、支持基线
- 流程列表组件：2509基线后支持
- 标准流程列表：2507（单独出过hotfix:weaver-workflow-list-1.71.0-hotfix17）、2511基线后默认支持
  
### 3.3.2、event事件说明
| 事件名称 | 说明 | 入参类型 |
| --- | --- | --- |
| wflPortalOrder | 流程列表组件-data接口，关联其它表进行自定义排序 | com.weaver.workflow.common.dto.list.hook.remote.params.portal.WflPortalRemoteHookParams |
| wflCusRelate | 标准流程列表-data接口，关联其它表进行自定义排序 | Map<String,Object>|
  
### 3.3.3、入参说明

>流程列表组件参数
  
| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| originOrderList | List<com.weaver.workflow.common.entity.list.requestlist.RequestListOrderEntity> | 标准排序字段 |
| originTableAlias | String | 标准表别名，用户和二开表join(2011基线支持使用标准提供的自定义关联表，如果使用标准的无需使用该参数，标准会进行自动拼接) |
| portalListParam | Map<String,Object> | 流程列表组件接口/getPortalListData 对应入参 |

>标准流程列表参数
  
| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| originOrderList | List<com.weaver.workflow.common.entity.list.requestlist.RequestListOrderEntity> | 标准排序字段 |
| originTableAlias | String | 标准表别名，用户和二开表join(2011基线支持使用标准提供的自定义关联表，如果使用标准的无需使用该参数，标准会进行自动拼接) |
| listParams | Map<String,Object> | 对应前台/getTodoListData接口的入参 |
  
### 3.3.4、示例
>2509基线示例，绑定自定义表，同数据库实例下，可以是建模表、自己建的表等（不推荐）
```java
package com.weaver.workflow.list.base.util.hook.test;

import com.alibaba.fastjson.JSONObject;
import com.weaver.loom.api.annotation.RegHook;
import com.weaver.loom.context.register.AbstractRegHookEvent;
import com.weaver.workflow.common.dto.list.hook.remote.params.portal.WflPortalRemoteHookParams;
import com.weaver.workflow.common.entity.list.requestlist.RequestListOrderEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: zhhy
 * @created: 2025/08/11 16:55
 */
@RegHook(module = "workflow", event = "wflPortalOrder", order = 0)
public class HookTest5 extends AbstractRegHookEvent {

    private static final Logger logger = LoggerFactory.getLogger(HookTest5.class);

    @Override
    public Object handle(Object[] args) throws Exception {
        WflPortalRemoteHookParams wflPortalRemoteHookParams = JSONObject.parseObject(JSONObject.toJSONString(args[0]), WflPortalRemoteHookParams.class);
        //标准排序字段
        List<RequestListOrderEntity> originOrderList = wflPortalRemoteHookParams.getOriginOrderList();
        //标准表别名
        String originTableAlias = wflPortalRemoteHookParams.getOriginTableAlias();
        
        //返回值
        Map<String, Object> res = new HashMap<>();
        List<RequestListOrderEntity> secondOrderList = new ArrayList<>();
        //自定义排序字段
        RequestListOrderEntity requestListOrderEntity = new RequestListOrderEntity();
        secondOrderList.add(requestListOrderEntity);
        //如果需要标准的排序字段，可以add一下，如果不需要直接返回
        //secondOrderList.addAll(originOrderList);
        res.put("secondOrderList", secondOrderList);
        //关联关系SQL片段
        res.put("joinTableAndRelationSql", " inner join 自定义表 cus_table on "+originTableAlias+".requestid = cus_table.xxx ");
        return res;
    }

}

```

>使用标准内置扩展表机制

>内置表文档说明 [点击查看](https://weapp.eteams.cn/ecode/playground/doc/share/view/1222521604282310656)
```java
package com.weaver.workflow.list.base.util.hook.test;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.weaver.loom.api.annotation.RegHook;
import com.weaver.loom.context.register.AbstractRegHookEvent;
import com.weaver.workflow.common.entity.list.requestlist.RequestListOrderEntity;
import com.weaver.workflow.common.util.DataTransUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: zhhy
 * @created: 2025/07/29 09:50
 */
@RegHook(module = "workflow", event = "wflCusRelate", order = 0)
public class HookTest6 extends AbstractRegHookEvent {

    @Override
    public Object handle(Object[] args) throws Exception {
        //使用标准表的情况
        Map<String, Object> params = JSONObject.parseObject(JSONObject.toJSONString(args[0]), new TypeReference<Map<String, Object>>() {});
        boolean useStandardRelateTable = true;
        if(useStandardRelateTable){
            return userStandard(params); //后续都使用这个逻辑
        }else {
            return userCusUfTable(params);
        }
    }

    /**
     * 使用标准自带的关联表，二开无需关心表名，只需处理排序字段（排序字段需要时标准关联表上支持的字段，注意：只能是自定义字段 column开头的字段）
     * 标准只支持left join最终拼接示例：left join wfl_relation_request_user wrru on wrru.requestid = t1.requestid and wrru.user_master_id = t1.user_master_id and wrru.delete_type = 0
     * @param params
     * @return
     */
    private Object userStandard(Map<String, Object> params){
        Map<String, Object> resMap = new HashMap<>();
        List<RequestListOrderEntity> originOrderList = JSONObject.parseObject(JSONObject.toJSONString(params.get("originOrderList")), new TypeReference<List<RequestListOrderEntity>>(){});
        RequestListOrderEntity requestListOrderEntity = new RequestListOrderEntity();
        requestListOrderEntity.setOrderKey(" (case when column_int_0 is null then 999 else column_int_1 end) ");
        requestListOrderEntity.setAsc(true);
        originOrderList.add(0, requestListOrderEntity);
        resMap.put("secondOrderList", originOrderList);
        resMap.put("useStandardRelateTable", true); //传这个属性  标准会自动进行关联表的拼接，二开无需处理
        return resMap;
    }

    /**
     * 使用自定义关联表，后续不再建议使用，后续可以使用标准提供的自定义关联表
     * @param params
     * @return
     */
    @Deprecated
    private Object userCusUfTable(Map<String, Object> params){
        Map<String, Object> resMap = new HashMap<>();
        String alias = DataTransUtil.null2String(params.get("originTableAlias"));
        String joinStr = " left join uf_xxx cus_t on cus_t.requestid = "+alias+".requestid and cus_t.user_master_id = "+alias+".user_master_id ";
        List<RequestListOrderEntity> originOrderList = JSONObject.parseObject(JSONObject.toJSONString(params.get("originOrderList")), new TypeReference<List<RequestListOrderEntity>>(){});
        RequestListOrderEntity requestListOrderEntity = new RequestListOrderEntity();
        requestListOrderEntity.setOrderKey("cus_t.column_int_1");
        requestListOrderEntity.setAsc(true);
        originOrderList.add(0, requestListOrderEntity);
        resMap.put("secondOrderList", originOrderList);
        resMap.put("joinTableAndRelationSql", joinStr);
        return resMap;
    }

}

```
>标准内置扩展表机制 (流程列表组件)
```java
package com.weaver.workflow.list.base.util.hook.test;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.weaver.loom.api.annotation.RegHook;
import com.weaver.loom.context.register.AbstractRegHookEvent;
import com.weaver.workflow.common.entity.list.requestlist.RequestListOrderEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: zhhy
 * @created: 2025/08/11 16:55
 */
@RegHook(module = "workflow", event = "wflPortalOrder", order = 0)
public class HookTest5 extends AbstractRegHookEvent {

    private static final Logger logger = LoggerFactory.getLogger(HookTest5.class);

    @Override
    public Object handle(Object[] args) throws Exception {
        Map<String, Object> res = new HashMap<>();
        Map<String, Object> params = JSONObject.parseObject(JSONObject.toJSONString(args[0]), new TypeReference<Map<String, Object>>(){});
        //标准排序字段
        List<RequestListOrderEntity> originOrderList = JSONObject.parseObject(JSONObject.toJSONString(params.get("originOrderList")), new TypeReference<List<RequestListOrderEntity>>() {});
        RequestListOrderEntity requestListOrderEntity = new RequestListOrderEntity();
        requestListOrderEntity.setOrderKey(" (case when column_int_0 is null then 999 else column_int_1 end) ");
        requestListOrderEntity.setAsc(true);
        originOrderList.add(0, requestListOrderEntity);
        //自定义排序字段
        res.put("secondOrderList", originOrderList);
        //关联关系SQL片段
        res.put("useStandardRelateTable", true); //传这个属性  标准会自动进行关联表的拼接，二开无需处理
        return res;
    }

}

```
  
  
## 3.4、关联流程，快捷搜索条件支持二开口子覆写

### 3.4.1支持基线
2509基线后支持
  
### 3.4.2、event事件说明
| 事件名称 | 说明 | 入参类型 |
| --- | --- | --- |
| wflBrowserQuickSearchCdt | 关联流程快捷搜索口子抛出 | Map<String,Object> |
  
### 3.4.3、入参说明
> Map中的入参属性
  
| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| userId | Long | 当前登录人用户ID |
| tenantKey | String | 当前登录人租户名称 |
  
### 3.4.4、示例
```java
package com.weaver.workflow.list.base.util.hook.test;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.weaver.loom.api.annotation.RegHook;
import com.weaver.loom.context.register.AbstractRegHookEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: zhhy
 * @created: 2025/06/19 16:55
 */
@RegHook(module = "workflow", event = "wflBrowserQuickSearchCdt", order = 0)
public class HookTest4 extends AbstractRegHookEvent {

    private static final Logger logger = LoggerFactory.getLogger(HookTest4.class);

    @Override
    public Object handle(Object[] args) throws Exception {
        logger.info("HookTest3:{}", JSONObject.toJSONString(args));
        //获取value
        Map<String, Object> stringObjectMap = JSONObject.parseObject(JSONObject.toJSONString(args[0]), new TypeReference<Map<String, Object>>() {});
        Map<String, String> quickSearchDatas = JSONObject.parseObject(JSONObject.toJSONString(stringObjectMap.get("quickSearchDatas")), new TypeReference<Map<String, String>>() {});
        String value = quickSearchDatas.get("requestname");
        Map<String, Object> res = new HashMap<>();
        // 覆写标题快捷搜索
        res.put("requestname", " ( t1.requestid in  (select 1 from weaver_wfp.wfp_base where delete_type = 0 and workflowname like '%"+value+"%')) ");
        return res;
    }

}

```
  
## 3.5、流程浏览按钮支持选到统一待办异构系统流程数据

### 3.5.1、支持基线
2507基线及以后支持
  
### 3.5.2、对接方式

> 给浏览按钮的commonparams增加参数needIutData=true，代表需要统一待办推送的异构系统数据

效果如图：


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

### 3.5.3、返回值说明
> 异构系统流程数据，会额外返回关联的外部系统相关信息
效果如图：


![](${appMdRes}/1767840300-image.png)
>属性含义说明：
~~~
requestCode: 外部系统流程id
sysCode: 外部系统编码
workflowCode: 外部系统工作流id
~~~

### 3.5.4、选择的统一待办数据支持口子拼接sql片段

**场景1：**

>以张三为例，默认查询的是张三本人参与的流程数据，支持口子扩展，允许在此范围基础上再拼接自定义sql片段过滤数据，比如过滤出李四也参与的流程数据。

对接步骤如下：
  
**第1步：**

> 给流程服务的数据库，wfl_sql_segment表插入2条数据：

参考如下sql：
~~~
insert into wfl_sql_segment(id,creator,create_time,update_time,tenant_key,delete_type,sql_key,sql_content)     values(1,111111,'2026-01-04 13:52:44','2026-01-04 13:52:44','tbuvblcfxp',0,1,'exists (select 1 from wfl_iut_todo_data where wfl_iut_todo_data.request_id = iutdata.request_id and wfl_iut_todo_data.user_master_id in($userMasterIds$))')

insert into wfl_sql_segment(id,creator,create_time,update_time,tenant_key,delete_type,sql_key,sql_content)     values(2,111111,'2026-01-04 13:52:44','2026-01-04 13:52:44','tbuvblcfxp',0,2,'exists (select 1 from wfl_iut_done_data where wfl_iut_done_data.request_id = iutdata.request_id and wfl_iut_done_data.user_master_id in($userMasterIds$))')

~~~
注意：租户key要替换成自己的，主键id保证不重复即可，效果如下图：


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


**第2步：**

> 给浏览按钮的commonparams增加参数sqlSegmentList，是个数组，代表自定义的sql片段信息集合

效果如图：
![](${appMdRes}/1767933666-image.png)
入参sqlSegmentList详细属性说明：

~~~
"sqlSegmentList": [
      {
        "sqlKey": 1,
        "sqlParams": {
          "userMasterIds":"882220199961698305,882220199961698306"
        }
      },
      {
        "sqlKey": 2,
        "sqlParams": {
          "userMasterIds":"882220199961698305,882220199961698306"
        }
      }
    ]
~~~

sqlKey含义说明：1是待办表sql，2是已办表sql 和wfl_sql_segment表的sql_key字段对应

sqlParams含义说明：sql片段中用到的动态参数值，比如传李四的用户ID，有多个的支持逗号分割
  
**注意：**
  
1、sqlParams中的key是参数名称，key的名称要和sql片段中的占位符对应，以$$占位，比如上述例子中传的userMasterIds，它的值会被替换到sql片段的$userMasterIds$中，生成最终sql。后续如果要扩展其它参数可以自己定义，只要跟sql片段中的占位符匹配即可

2、sqlParams中的value是参数值，value的值，只能是数字或者字符串，长度不能超过30，不能包含空格

**场景2：**

>假设有两个第三方系统A、B都往同一个E10系统推送数据，现在想要在E10系统中仅选择系统A推送的数据，不选B系统推送的，可以通过不同的应用系统标识过滤，具体实现方式参考如下步骤：

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

**第1步：**

> 给流程服务的数据库，wfl_sql_segment表插入2条数据：

参考如下sql：
~~~
insert into wfl_sql_segment(id,creator,create_time,update_time,tenant_key,delete_type,sql_key,sql_content)     values(1,111111,'2026-01-04 13:52:44','2026-01-04 13:52:44','tbuvblcfxp',0,1,'iutdata.sys_code in($sysCode$)')

insert into wfl_sql_segment(id,creator,create_time,update_time,tenant_key,delete_type,sql_key,sql_content)     values(2,111111,'2026-01-04 13:52:44','2026-01-04 13:52:44','tbuvblcfxp',0,2,'iutdata.sys_code in($sysCode$)')
~~~
注意：租户key要替换成自己的，主键id保证不重复即可

**第2步：**

> 给浏览按钮的commonparams增加参数sqlSegmentList，是个数组，代表自定义的sql片段信息集合

入参sqlSegmentList详细属性说明：

~~~
"sqlSegmentList": [
      {
        "sqlKey": 1,
        "sqlParams": {
          "sysCode":"'sys_code1','sys_code2'"
        }
      },
      {
        "sqlKey": 2,
        "sqlParams": {
          "sysCode":"'sys_code1','sys_code2'"
        }
      }
    ]
~~~
sqlKey含义说明：1是待办表sql，2是已办表sql 和wfl_sql_segment表的sql_key字段对应

sqlParams含义说明：sql片段中用到的动态参数值，比如传A系统的应用系统标识，有多个的支持逗号分割
  
**注意：**
  
1、sqlParams中的key是参数名称，key的名称要和sql片段中的占位符对应，以$$占位，比如上述例子中传的sysCode，它的值会被替换到sql片段的$sysCode$中，生成最终sql。后续如果要扩展其它参数可以自己定义，只要跟sql片段中的占位符匹配即可

2、sqlParams中的value是参数值，value的值，用逗号分割以后，单个值只能是数字或者字符串，长度不能超过30，不能包含空格

## 3.6、接收统一待办数据后置埋点
### 3.6.1、支持基线
2605基线后支持
### 3.6.2、event事件
| 事件名称 | 说明 | 入参类型 |
| --- | --- | --- |
| wflIutReceiveAfter | 接收统一待办数据后置埋点 | Map<String,Object> |
  
### 3.6.3、入参说明
> Map中的入参属性

| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| originIutCenterData | com.weaver.workflow.common.dto.ofs.RequestIutMessageDto | 统一待办原始报文 |

### 3.6.4、示例
```java
package com.weaver.workflow.list.base.util.hook.test.test;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.weaver.loom.api.annotation.RegHook;
import com.weaver.loom.context.register.AbstractRegHookEvent;
import com.weaver.workflow.common.dto.ofs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;

/**
 * @author: zhhy
 * @created: 2026/04/30 21:28
 */
@RegHook(module = "workflow", event = "wflIutReceiveAfter", order = 0)
public class HookTest2 extends AbstractRegHookEvent {

    private static final Logger logger = LoggerFactory.getLogger(HookTest2.class);

    @Override
    public Object handle(Object[] args) throws Exception {
        logger.info("HookTest2:{}", JSONObject.toJSONString(args));
        if (args != null && args.length > 0 && args[0] != null) {
            HashMap<String, Object> params = JSONObject.parseObject(JSONObject.toJSONString(args[0]), new TypeReference<HashMap<String, Object>>() {
            });
            if (!CollectionUtils.isEmpty(params) && params.containsKey("originIutCenterData")) {
                RequestIutMessageDto originIutCenterData = JSONObject.parseObject(JSONObject.toJSONString(params.get("originIutCenterData")), RequestIutMessageDto.class);
                //统一待办工作流信息
                RequestIutWorkflowDto workflowDto = originIutCenterData.getWorkflowDto();
                //requestbase：流程基本信：标题、workflowCode、requestCode等基本信息
                RequestIutRequestBaseDto requestBaseDto = originIutCenterData.getRequestBaseDto();
                int deleteType = requestBaseDto.getDeleteType();
                if (deleteType != 0) {
                    //当前requestCode对应的统一待办数据被删除了
                }
                //待办已办信息
                List<RequestIutDataDto> iutDataDtoList = originIutCenterData.getIutDataDtoList();
                if (!CollectionUtils.isEmpty(iutDataDtoList)) {
                    iutDataDtoList.forEach(iutDataDto -> {
                        //requestCode
                        String requestCode = iutDataDto.getRequestCode();
                        //用户主身份ID
                        Long userMasterId = iutDataDto.getUserMasterId();
                        //isremark < 100 待办; isremark >= 100 已办
                        Integer isremark = iutDataDto.getIsremark();
                        //deleteType == 0 正常有效数据；deleteType != 0 数据被删除了
                        int userDataDeleteType = iutDataDto.getDeleteType();
                        //TODO 做一些自定义的处理
                    });
                }
            }
        }
        return new HashMap<>();
    }

}

```


# 四、常用表说明/Sql

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

> 地址：[点击查看](https://weapp.eteams.cn/ecode/playground/doc/share/view/1191820469597757441)

  

