Skip to main content

Custom page use step components to display process operations

1. Usage scenarios

InCustom page viewing process efficiencyIn the document, the node information is displayed in the tree structure of the table within YIDA to view the approval efficiency of the process. This document uses the step component to display the process information of the process within YIDA.

2. Video tutorial

To be added, please look forward...

3. Procedure

Prepare two pages: process page and custom page

3.1 Step 1: create a process page

Create a process page>Complete process approval node settings>Create test data

(The process page settings are shown in Figure 3.1-1)

Figure 3.1-1 setup process page

3.2 Step 2: Create a custom page

The custom page allows you to view information such as the approval node, approver, and approval time in real time. You need to use two data sources. Used here separatelySearch for process instance IDs based on criteriaAndObtain approval RecordsThe interface data is used as the data source.

3.2.1 define remote data sources

To obtain the monitoring status of the process in real time, you must first call the interface to search for the instance ID and complete the filtering of related processes, you can obtain data such as the actions and approval time of a data approval node by obtaining approval records and display them on the custom page. (As shown in figure 3.2.1-1)

Figure 3.2.1-1 remote data source configuration


On the data source editing page, turn off the automatic data source loading option. In order to achieve the effect of paging and total, data is processed after the data source is called, which is used to return the data of instance ID, total number and current page number. The data processing code is as follows:

The following code can be directly copied to the didfetch data processing of the API for obtaining the instance ID.

function didFetch(content) {
//返回实例ID,总条数和当前页码
let result = {
processInstanceId: content.data,
totalCount: content.totalCount,
currentPage: content.currentPage,
}
return result; // 重要,需返回 result
}

3.2.2 define variable data sources

Define Variable Data Sources time and datas, where datas data sources are used to bind table components and time data sources are used to store the total approval duration. (The definition method of variable data source is shown in Figure 3.2.2-1) (the binding method of table data source datas is shown in Figure 3.2.2-2)

Figure 3.2.2-1 define table-related variable data sources time and datas

Figure 3.2.2-2 binding table-related variable data source datas

Define the variable data source related to the step (the operation method is shown in Figure 3.2.2-3) and bind the variable data source (the operation method is shown in Figure 3.2.2-4). Implement the linkage between the step bar and the approval data.

Figure 3.2.2-3 define the data source condition,demoData, and status of related variables in step

Figure 3.2.2-4 binding steps related variable data sources

3.2.3 JS panel calls remote data sources and processes data

First, bind the initialization function didmount on the custom page. When binding, copy the following code to the JS panel. (As shown in figure 3.2.3-1)

After the data is processed, assign a value to the datas variable data source and change the table data field name. (As shown in figure 3.2.3-2)

Figure 3.2.3-1 binding didmount

Figure 3.2.3-2 change the data field name

The following code can be copied directly into the JS panel.

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 set table operation columns

Set the fields of table operation columns and bind processing functions. Click the "View steps" button to obtain and display the approval status of the current approval form, that is, the process status. (The setting method is shown in figure 3.2.4-1)

Figure 3.2.4-1 binding callback functions

The following code can be directly copied and edited in the JS panel.

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 add settings

Add the "add" button at the top of the table, click the button, and the page will jump to the process initiation page. After filling in the content, a new approval process will be initiated. (The setting method is shown in figure 3.2.5-1)

Figure 3.2.5-1 add tables

The following code can be directly copied and edited in the JS panel,Note: replace the link with the access link of the process page.

export function onActionBarItemClick() {
this.utils.router.push("https://www.aliwork.com/APP_JKH50FL33A0H8GJBQEHL/submission/FORM-N796637187UTSDMX1NVMJ4EYCAHL2GQPCKWTKY3?processCode=TPROC--N796637187UTSDMX1NVMJ4EYCAHL2ORPCKWTKZ3&" + {}, {}, true, true);
}

3.2.6 set pagination

You can set the pagination style of a table.

First, bind the function "onFetchData" to the trigger of "attribute-advanced-action setting-paging, search, and sort, and copy the following code to the page JS; (The function binding method is shown in figure 3.2.6-1)

Then, set the page "pageSize" in the "property-paging settings". Note: the number here should be the same as the remote data source configuration (figure 3.2.1-1) the request parameter-pageSize-parameter value is the same in, otherwise, display problems will occur. (The setting method is shown in figure 3.2.6-2)

Figure 3.2.6-1 table component binding action

Figure 3.2.6-2 change paging settings


Precondition: the remote data source that obtains the ID of the process instance performs didfetch data processing. timeshow methods have been defined in the JS panel.

The following code can be directly copied in the JS panel,Note: replace the formUuid of the process

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. Achieve results

Figure 4-1 effect demonstration

5. Try it online

For online experience, please go to the Developer Center.👉Step 1 show process

-------------------- Get the latest information YIDA, welcome to follow US--------------------

This doc is generated using machine translation. Any discrepancies or differences created in the translation are not binding and have no legal effect for compliance or enforcement purposes.
Copyright © 2024钉钉(中国)信息技术有限公司和/或其关联公司浙ICP备18037475号-4