• 首页
  • 产品中心
    • 数式Oinone四大产品

      低代码开发平台无代码开发平台集成开发平台AI大模型开发
    • 数式Oinone体系能力

      用户与组织权限管理文件管理消息中心国际化业务审计
    • 数式Oinone核心产品特性

      低无一体面向软件公司场景无限制应用级扩容可分可合
  • 服务中心
    • 客户服务

      预约演示方案咨询私有部署找人定制
    • 开发者

      问答下载
    • Oinone学院

      社区学习

    《精讲面向软件公司的低代码平台——以Oinone为例》

  • 合作伙伴
    渠道申请伙伴名录专家库
  • 关于数式
0571-88757863

Button:How to Display Workflow Approval Buttons in Business Model Lists


I. Scenario Overview

When we need to display approval buttons in the list of a business model, we can complete the extension through customization. This allows direct clicking on the action button in business data to navigate to the workflow to-do detail page for handling approvals or filling out tasks.

II. Solutions

(Ⅰ) First, add the userTaskList field in the business data model to store the workflow to-do data of the record

@Model.model(DemoItem.MODEL_MODEL)
@Model(displayName = "Test Product")
public class DemoItem extends IdModel {

    @Field.one2many
    @Field(displayName = "Workflow Task List", store = NullableBoolEnum.FALSE, invisible = true)
    @Field.Relation(store = false)
    private List<WorkflowUserTask> userTaskList;
}

(Ⅱ) Query the data of the current logged-in user in workflow tasks within the query method of business data

@Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "Query List", timeout = 50000)
@Function.fun(FunctionConstants.queryPage)
@Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API})
public Pagination<DemoItem> queryPage(Pagination<DemoItem> page, QueryWrapper<DemoItem> queryWrapper) {
    new DemoItem().queryPage(page, queryWrapper);

    List<Long> bizIds = page.getContent().stream().map(DemoItem::getId).collect(Collectors.toList());

    LambdaQueryWrapper<WorkflowUserTask> userTaskWrapper = new LambdaQueryWrapper<>();
    userTaskWrapper.setModel(WorkflowUserTask.MODEL_MODEL);
    userTaskWrapper.select(WorkflowUserTask::getId, WorkflowUserTask::getNodeDataBizId);
    userTaskWrapper.eq(WorkflowUserTask::getUserId, PamirsSession.getUserId())
    .eq(WorkflowUserTask::getModel, DemoItem.MODEL_MODEL)
    .eq(WorkflowUserTask::getStatus, WorkflowUserStatusEnum.ACTIVE)
    .in(WorkflowUserTask::getNodeDataBizId, bizIds);

    Pagination<WorkflowUserTask> userTaskPagination = new Pagination<>();
    userTaskPagination.setCurrentPage(1);
    userTaskPagination.setSize(200L);
    userTaskPagination.setSort(new Sort().addOrder(SortDirectionEnum.DESC, WorkflowUserTask::getCreateDate));

    List<WorkflowUserTask> userTasks = new WorkflowUserTask().queryListByWrapper(userTaskPagination, userTaskWrapper);
    Map<Long, WorkflowUserTask> map = userTasks.stream().collect(Collectors.toMap(WorkflowUserTask::getNodeDataBizId, v -> v, (a, b) -> a));
    page.getContent().forEach((item) -> {
        WorkflowUserTask workflowUserTask = map.get(item.getId());
        if (workflowUserTask != null) {
            item.setUserTaskList(Lists.newArrayList(workflowUserTask));
        }
    });
    return page;
}

(Ⅲ) Drag a server-side action into the operation column in the interface designer

(Ⅳ) Drag the workflow task list field userTaskList into the table column and hide this field

(Ⅴ) Frontend custom action component for navigating to the workflow to-do detail page

import {
  ActionType,
  ActionWidget,
  ClickResult,
  executeViewAction, RuntimeViewAction,
  ServerActionWidget,
  SPI, ViewActionTarget, ViewType, Widget
} from '@oinone/kunlun-dependencies';

// name is the action name dragged from the interface designer
@SPI.ClassFactory(ActionWidget.Token({ actionType: ActionType.Server, model: 'demo.DemoItem', name: 'uiServer0358d42817d64fe7908fe48dfce084d3' }))
  class WorkflowJumpActionWidget extends ServerActionWidget {

    @Widget.Reactive()
    public get invisible(): boolean {
      if (!this.activeRecords?.[0]?.userTaskList?.[0]?.id) {
        return true;
      }
      return super.invisible;
    }

    protected async clickAction(): Promise<ClickResult> {
      const menu = {"selectedKeys":["WorkflowMenus_WorkBenchMenu_ActiveUserTaskMenu"],"openKeys":["WorkflowMenus_WorkBenchMenu","WorkflowMenus_WorkBenchMenu_ActiveUserTaskMenu"]};
      const userTaskId = this.activeRecords?.[0]?.userTaskList?.[0]?.id;
      if (!userTaskId) {
        return;
      }
      executeViewAction(
        {
          viewType: ViewType.Form,
          resModuleName: 'workflow',
          model: 'workbench.WorkBenchWorkflowUserTaskActive',
          name: 'workflow_wait',
          target: ViewActionTarget.OpenWindow,
          sessionPath: '/workflow/WorkflowMenus_WorkBenchMenu_ActiveUserTaskMenu'
        } as RuntimeViewAction,
        undefined,
        undefined,
        {
          id: userTaskId,
          menu: JSON.stringify(menu)
        }
      );
    }
  }
Edit this page
Last Updated:1/15/26, 4:02 AM
Prev
Application:Introducing Qiankun Micro-Frontend
Next
Button:Passing Extra Parameters Across Pages
默认页脚
Copyright © 2026 Mr.Hope