Customize the page to monitor the efficiency of the entire application process
1. Use background
In 「Custom page viewing process efficiencyThe document displays the approval data in a process in the table component, so how to monitor the efficiency of all processes in the current application. This document describes how to monitor the efficiency of a single application.
2. Video tutorial
3. Procedure
3.1 Step 1: create a process page
Create two process pages, configure the required components and process approval node information, and enter some test data.
Figure 3.1-1 Flow Chart 1
Figure 3.1-2 Flow Chart 2
3.2 Step 2: Create a bottom table
Function: store the name of the flow chart and the name of the flow chart formUuid that you want to view in the application. Later, the data in the form will be obtained on the custom page and placed in the drop-down option to select the approval data on The View process page.
Bottom table
3.3 Step 3: Create a custom page
Required components:
"Drop-down Radio": configure options, display value configuration flow chart name, option value configuration flow chart formUuid.
"Table component": mainly configure the Operation Progress options in the operation column to control the progress percentage of the progress indicator. For more information, seeCustom page viewing process efficiency.
Progress indicator component: bind the percentage attribute to the variable data source, and turn off automatic rendering to control rendering and percentage based on the variable data source.
Components required for custom pages
3.3.1 define remote data sources
To obtain the monitoring status of the process in real time, it is called first. The interface that searches for the instance ID., filter the corresponding process and pass Interface for obtaining approval RecordsObtain data such as the actions and approval time of the data approval node and display it on the custom page.
Remote data source configuration
The data source is disabled for automatic loading. In order to achieve paging and total effects, data processing is used after the data source is called, and the instance ID, total number, and current page number are returned.
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
}
There are two ways to assign values to the option properties of the drop-down component:
a. The first method. Configure remote data sourcesSearch form instance details Obtain the data in the bottom table (for more information about the data in the bottom table, see step 3.2), turn on automatic loading, and process the data in the drop-down option format in the didfetch data processing, the option property of the drop-down option is bound to the remote data source (as shown in figure 3.3.1-1).
3.3.1-1 getDatas remote data source configuration
The following code can be directly copied didfetch data processing,Note: You need to replace the unique identifier of the component.
function didFetch(content) {
//处理成下拉单选的选项属性数据格式
const datasource = [];
content.data.map((item) => {
let arr = {
//text存储表单名称,value存储表单formUuid,唯一标识更改成底表内相对应的唯一标识
text: item.formData.textField_kto1kwz0,
value: item.formData.textField_kto1kwz2
}
datasource.push(arr)
})
return datasource; // 重要,需返回 datasource
}
B. The second method. You can directly set the display value and option value to flow chart name and flow chart formUuid in the custom option of the drop-down selection (as shown in figure 3.3.1-2).
3.3.1-2 custom option configuration
3.3.2 define variable data sources
Because the returned data is processed in a complex format, variable data sources time and datas are defined, and table components bind datas variable data sources.
Bind a variable data source to a table component
percent and condition control the percentage of progress indicator components and whether to render properties, respectively.
Variable data source
Bind a variable data source
3.3.3 pull-down radio binding action triggers the call
Bind a drop-down component
Change the data field name
The API method is used to obtain the value of the drop-down component, define the request parameters, and define the value, that is, the formUuid of the form, when the request parameters are defined, finally, enter parameters in the getInstanceIds remote data source to obtain the approval information of this page.
The following code can be directly copied in the JS panel,Note: You need to replace the unique identifier of the drop-down component.
export function onChange({value, actionType, item}) {
//控制切换时进度条组件不渲染,进度百分比为0
this.setState({
condition: false,
percent: 0
})
//清空datas变量数据源
this.setState({
datas : []
})
//通过API方法获取到下拉组件的value值,也就是formUuid
const uuid = this.$('select_kto1v6f2').getValue();
let newvalue = [];
//定义请求参数
const param_uuid = {
formUuid: uuid
}
//在getInstanceIds远程数据源中携带参数计算出选择到的页面审批信息
this.dataSourceMap.getInstanceIds.load(param_uuid).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) => {
//存储树形表格内的children格式,详情表格格式可以点击查看表格数据源属性中的编辑代码或参考文档:https://developers.aliwork.com/docs/components/advanced/table#%E7%BB%84%E4%BB%B6%E5%B1%9E%E6%80%A7
const children = [];
//循环一个流程中的所有节点的审批记录,最终将判断好的数据格式push到children中
for (let item = 0; item < content.length; item++) {
//判断当审批状态是next或submit或doing时没有本节点的审批时间,所以不计算本节点到上一个节点所用审批时长
if (content[item].actionExt === "next" || content[item].actionExt === "submit" || content[item].actionExt === "doing") {
//重新提交的审批状态是submit,这里对它作判断计算了审批时长
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 {
//没有本节点审批时间的不加time
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,
time: state.time,
children: children,
onlyid: params.processInstanceId
}
newvalue.push(data);
}
//循环获取数据列的数据,当前的审批节点数据push在数据列中
for (let j = 0; j < content.length; 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,
}
newvalue.push(data);
}
}
//携带总计条数和数据列的值赋值给datas变量数据源
let result = {
data: newvalue,
totalCount: response.totalCount,
}
this.setState({
datas: result
})
})
}
})
}
//timeshow方法,传入结束时间和开始时间计算时间差
export function timeshow(num_end, num_start) {
const num = (num_end - num_start) / 1000;
const day = Math.floor(num / 86400) + "d ";
const hour = Math.floor((num % 86400) / 3600) + "h ";
const min = Math.floor(((num % 86400) % 3600) / 60) + "min ";
const s = Math.floor(((num % 86400) % 3600) % 60) + "s ";
if (day == "0d ") {
//判断当天数等于0d时
if (hour == "0h ") {
//在当天数等于0d时,继续判断当小时等于0h时
if (min == "0min ") {
//在当天数等于0d时,当小时等于0h时,继续判断分等于0时
//返回秒
return `${s}`
} else {
//min不等于0时,则将分钟和秒返回
return `${min}${s}`
}
} else {
//天数等于0d,小时不等于0h时,返回小时分钟
return `${hour}${min}${s}`
}
} else {
//当天数不等于0d时,将天数小时分钟拼接一起返回
return `${day}${hour}${min}${s}`
}
}
Effect demonstration
3.3.4 set the viewing progress of the operation column
Set the action column of the table>Add an action item named view progress>Click edit>Bind callback actions>Bind custom rendering
Set Action columns
The following code can be directly copied in the JS panel. The binding name can be configured by yourself. The name defined here is:
- The name of the callback function to be bound is onActionClick2.
- The custom rendering name is actionRender1.
export function onActionClick2(rowData) {
//如果审批完成了,进度条渲染并且百分比为100
if (rowData.actionExt == "Completed"){
this.setState({
condition:true,
percent: 100
})
}else{
//审批未完成,遍历审批节点信息,如果审批节点已完成 num 加一,最终用 num 和审批节点的总长度计算出百分比
let child = rowData.children;
let num = 0;
for (let p = 0; p < child.length;p++){
console.log(child)
if (child[p].actionExt != "next" && child[p].actionExt !="doing" ){
num ++;
}
console.log(num, child.length)
this.setState({
condition: true,
percent: (num / child.length)*100
})
}
}
}
//点击箭头展开审批节点信息时,不在操作列中出现查看进度的操作
export function actionRender1(title, rowData) {
if(!rowData.children){
return false;
}
return title; // return false 则不显示
}
Effect demonstration
3.3.5 implement pagination data display
Table component binding action
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: You need to replace the unique identifier of the drop-down radio component.
export function onFetchData(params) {
//清空datas变量数据源,不清空有可能会造成翻页时数据展示错误
this.setState({
datas: []
})
// 如果是搜索的话翻页重置到 1
if (params.from === 'search') {
params.currentPage = 1;
}
//定义newvalue数组,存放表格数据
const newvalue = [];
//通过API方法获取到下拉组件的value值,也就是formUuid
const uuid = this.$('select_kto1v6f2').getValue();
//配置获取实例id数据源参数,获取翻页后的第params.currentPage页数据
const param_1 = {
formUuid: uuid,
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
})
})
}
})
}
Effect demonstration
3.3.6 when initializing, the table prompts "Please select the process page name"
Effect demonstration
The following code can be copied directly into the JS panel.
export function didMount() {
document.getElementsByClassName("next-table-empty")[0].innerHTML = "请选择流程页面名称"
}
4. Achieve results
Effect demonstration
5. Try it online
For online experience, please go to the Developer Center.👉Single Application full process efficiency monitoring
-------------------- Get the latest information YIDA, welcome to follow US--------------------