1. 使用场景
在自定义页面查看流程效率文档中,完成了在宜搭内使用表格的树形结构展示节点信息,用于查看流程的审批效率。本文档将在宜搭内使用步骤条组件来展示流程的工序信息。
2.视频教程
待补充,敬请期待...
3. 操作步骤
准备2个页面,分别是流程页面和自定义页面
3.1 步骤一:创建流程页面
创建一个流程页面 >> 完成流程审批节点设置 >> 创建测试数据
(流程页面设置如图3.1-1所示)
图3.1-1 设置流程页面
3.2 步骤二:创建自定义页面
自定义页面用于实现实时查看审批节点、审批人、审批时间等信息,需要使用两个数据源。这里分别使用了根据条件搜索流程实例 ID和获取审批记录接口数据作为数据源。
3.2.1 定义远程数据源
为了实时获取流程的监控情况,要先调用搜索实例ID的接口,完成对相关的流程的筛选后,通过获取审批记录的接口将数据审批节点的动作和审批时间等数据获取出来,在自定义页面进行展示。(如图3.2.1-1所示)
图3.2.1-1 远程数据源配置
在数据源编辑页面将数据源自动加载选项关闭。后续为了实现分页和总计的效果,在调用数据源后进行了数据处理,用于返回实例ID,总条数和当前页码的数据。数据处理代码如下:
下述代码可直接复制在获取实例ID接口的didfetch数据处理内
function didFetch(content) { //返回实例ID,总条数和当前页码 let result = { processInstanceId: content.data, totalCount: content.totalCount, currentPage: content.currentPage, } return result; // 重要,需返回 result }
3.2.2 定义变量数据源
定义变量数据源time和datas,其中datas数据源用于表格组件的绑定,time数据源用于存储总的审批时长。(变量数据源定义方法如图3.2.2-1所示)(表格数据源datas绑定方法如图3.2.2-2所示)
图3.2.2-1 定义表格相关变量数据源time和datas
图3.2.2-2 绑定表格相关变量数据源datas
定义步骤条相关变量数据源(操作方法如图3.2.2-3所示),并进行变量数据源的绑定(操作方法如图3.2.2-4所示)。实现步骤条与审批数据进行联动。
图3.2.2-3 定义步骤条相关变量数据源condition,demoData及status
图3.2.2-4 绑定步骤条相关变量数据源
3.2.3 JS面板调用远程数据源并进行数据处理
首先,在自定义页面绑定初始化函数didmount,绑定时将代码下述复制到JS面板中。(如图3.2.3-1所示)
将数据处理完成后,赋值给datas变量数据源,并更改表格数据字段名称。(如图3.2.3-2所示)
图3.2.3-1 绑定didmount动作
图3.2.3-2 更改数据字段名称
下述代码可直接复制在 JS 面板内
export function didMount() { //用作汇总每条审批记录的数据 let value = []; //调用getInstanceIds远程数据源获取实例ID,并循环将实例ID this.dataSourceMap.getInstanceIds.load().then((response) => { //console.log("response", response)//[实例ID,实例ID,...] let res = response.processInstanceId //循环将每条实例ID用作参数调用一次接口 for (let i = 0; i < res.length; i++) { const params = { processInstanceId: res[i], } //调用getOperationRecords接口获取每条流程的审批记录 this.dataSourceMap.getOperationRecords.load(params).then((content) => { const children = []; for (let item = 0; item < content.length; item++) { if (content[item].actionExt === "next" || content[item].actionExt === "submit" || content[item].actionExt === "doing") { if (content[item].showName === "重新提交") { this.setState({ time: timeshow(content[item].operateTime, content[item - 1].operateTime) }) let children_data = { actionExt: content[item].actionExt, active: content[item].showName, active_name: content[item].operatorName, active_time: content[item].operateTime, time: state.time, onlyid: params.processInstanceId } children.push(children_data); } else { let children_data = { actionExt: content[item].actionExt, active: content[item].showName, active_name: content[item].operatorName, active_time: content[item].operateTime, onlyid: params.processInstanceId } children.push(children_data); } } else { this.setState({ time: timeshow(content[item].operateTime, content[item - 1].operateTime) }) let children_data = { actionExt: content[item].actionExt, active: content[item].showName, active_name: content[item].operatorName, active_time: content[item].operateTime, time: state.time, onlyid: params.processInstanceId } children.push(children_data); } } //判断是HISTORY类型时,计算总审批时长,最终审批时间-提交时间 if (content[content.length - 1].type === "HISTORY") { const num_end = content[content.length - 1].operateTime; const num_start = content[0].operateTime; this.setState({ time: timeshow(num_end, num_start) }) let data = { //发起人和发起时间是content[0]里的数据,其余是获取的最后一条数据 create_name: content[0].operatorName, create_time: content[0].operateTime, actionExt: "Completed", active: content[content.length - 1].showName + "(已完成)", active_name: content[content.length - 1].operatorName + "(已完成)", active_time: content[content.length - 1].operateTime, action: content[content.length - 1].actionExt, children: children, time: state.time, onlyid: params.processInstanceId } value.push(data); } //如果不是HISTORY类型,那就是没有结束的审批流程 //需要循环获取数据列的数据,将当前的审批节点数据push在数据列中 for (let j = 0; j < content.length; j++) { // console.log("content[j]", content[j]) if (content[j].type === "TODO") { let data = { //发起人和发起时间是content[0]里的数据,其余变成TODO类型时的数据也就是进行中的那条数据 create_name: content[0].operatorName, create_time: content[0].operateTime, actionExt: content[j].actionExt, active: content[j].showName + "(当前)", active_name: content[j].operatorName + "(当前)", active_time: content[j].activeTime, children: children, onlyid: params.processInstanceId, } value.push(data); } } //携带总计条数和数据列的值赋值给datas变量数据源 let result = { data: value, totalCount: response.totalCount, } this.setState({ datas: result }) }) } }) }
3.2.4 设置表格操作列
设置表格操作列的字段,绑定处理函数。实现用户点击“查看步骤”操作按钮,获取并展示当前审批单审批状态,即工序状态。(设置方法如图3.2.4-1所示)
图3.2.4-1 绑定回调函数
下述代码可直接复制编辑 JS 面板内
export function onActionClick(rowData) { //清空变量status,防止累计push多条数据到status中 status = []; //点击操作列时步骤条渲染 this.setState({ condition: true }) //如果审批状态完成了,那么遍历该流程所有节点的步骤数据status值为finish //如果审批状态未完成,那么遍历该流程所有节点,doing类型的审批状态status值为process,next类型的status值为wait,其余类型的status值为finish //status_chilrden里面的数据参考步骤条数据格式,最终push到status中:https://www.yuque.com/yida/support/gzllee#Z8nrr if (rowData.actionExt == "Completed") { let child = rowData.children for (let i = 0; i <= child.length - 1; i++) { let status_chilrden = { "title": "工序" + (i + 1), "content": child[i].active, "status": "finish", } status.push(status_chilrden) } } else { let child = rowData.children for (let i = 0; i < child.length - 1; i++) { if (child[i].actionExt == "doing") { this.setState({ status: "process" }) } else if (child[i].actionExt == "next") { this.setState({ status: "wait" }) } else { this.setState({ status: "finish" }) } let status_chilrden = { "title": "工序" + (i + 1), "content": child[i].active, "status": state.status, } status.push(status_chilrden) } } this.setState({ demoData: status }) }
3.2.5 设置新增
在表格顶部增加"新增"按钮,点击按钮,页面跳转到流程发起页面,填写内容后,实现发起新的审批流程。(设置方法如图3.2.5-1所示)
图3.2.5-1 设置表格新增
下述代码可直接复制编辑 JS 面板内,注意:链接替换成流程页面的访问链接。
export function onActionBarItemClick() { this.utils.router.push("https://www.aliwork.com/APP_JKH50FL33A0H8GJBQEHL/submission/FORM-N796637187UTSDMX1NVMJ4EYCAHL2GQPCKWTKY3?processCode=TPROC--N796637187UTSDMX1NVMJ4EYCAHL2ORPCKWTKZ3&" + {}, {}, true, true); }
3.2.6 设置分页
实现表格分页样式的设定。
首先,在"属性-高级-动作设置-分页、搜索、排序时触发处绑定函数"onFetchData",并将下述代码复制到页面JS中;(函数绑定方法如图3.2.6-1所示)
然后,在"属性-分页设置"中进行页面"pageSize"的设置,注意:此处的数字应与远程数据源配置(图3.2.1-1)中"请求参数-pageSize-参数值"相同,否则会造成展示问题。(设置方法如图3.2.6-2所示)
图3.2.6-1 表格组件绑定动作
图3.2.6-2 更改分页设置
前置条件:获取流程实例ID的远程数据源内做didfetch数据处理,已在JS面板内定义timeshow方法。
下述代码可直接复制在JS面板内,注意:替换流程的formUuid
export function onFetchData(params) { //清空datas变量数据源,不清空有可能会造成翻页时数据展示错误 //点击操作翻页时步骤条不渲染 this.setState({ datas: [], condition:false }) // 如果是搜索的话翻页重置到 1 if (params.from === 'search') { params.currentPage = 1; } //定义newvalue数组,存放表格数据 const newvalue = []; //配置获取实例id数据源参数,获取翻页后的第params.currentPage页数据 const param_1 = { formUuid: "FORM-N796637187UTSDMX1NVMJ4EYCAHL2GQPCKWTKY3", pageSize: 5, currentPage: params.currentPage, } this.dataSourceMap.getInstanceIds.load(param_1).then((response) => { let res = response.processInstanceId for (let i = 0; i < res.length; i++) { const params = { processInstanceId: res[i], } this.dataSourceMap.getOperationRecords.load(params).then((content) => { const children = []; for (let item = 0; item < content.length; item++) { if (content[item].actionExt === "next" || content[item].actionExt === "submit" || content[item].actionExt === "doing") { if (content[item].showName === "重新提交") { this.setState({ time: timeshow(content[item].operateTime, content[item - 1].operateTime) }) let children_data = { actionExt: content[item].actionExt, active: content[item].showName, active_name: content[item].operatorName, active_time: content[item].operateTime, time: state.time, onlyid: params.processInstanceId } children.push(children_data); } else { let children_data = { actionExt: content[item].actionExt, active: content[item].showName, active_name: content[item].operatorName, active_time: content[item].operateTime, onlyid: params.processInstanceId } children.push(children_data); } } else { this.setState({ time: timeshow(content[item].operateTime, content[item - 1].operateTime) }) let children_data = { actionExt: content[item].actionExt, active: content[item].showName, active_name: content[item].operatorName, active_time: content[item].operateTime, time: state.time, onlyid: params.processInstanceId } children.push(children_data); } } for (let j = 0; j < content.length; j++) { if (content[j].type === "TODO") { let data = { create_name: content[0].operatorName, create_time: content[0].operateTime, actionExt: content[j].actionExt, active: content[j].showName + "(当前)", active_name: content[j].operatorName + "(当前)", active_time: content[j].activeTime, children: children, onlyid: params.processInstanceId, } newvalue.push(data); } } if (content[content.length - 1].type === "HISTORY") { const num_end = content[content.length - 1].operateTime; const num_start = content[0].operateTime; this.setState({ time: timeshow(num_end, num_start) }) let data = { create_name: content[0].operatorName, create_time: content[0].operateTime, actionExt: "Completed", active: content[content.length - 1].showName + "(已完成)", active_name: content[content.length - 1].operatorName + "(已完成)", active_time: content[content.length - 1].operateTime, action: content[content.length - 1].actionExt, time: state.time, children: children, onlyid: params.processInstanceId } newvalue.push(data); } //currentPage控制页码选中,totalCount控制总计条数,data是控制数据 let result = { data: newvalue, totalCount: response.totalCount, currentPage: response.currentPage } this.setState({ datas: result }) }) } }) }
4. 实现效果
图4-1 效果演示
5. 在线试玩
在线体验请移步开发者中心 ? 步骤条展示流程工序
宜搭为了更好的优化宜搭使用手册内容和质量,占用您3-5分钟时间,辛苦填写一下文档反馈问卷。文档反馈问卷是匿名提交,同时问卷信息仅用于宜搭文档体验反馈收集,感谢您对宜搭的支持!点此填写调研问卷