如何通过业务数据拿到工作流用户任务待办

  1. 在模型里面建一个非存储字段,用来传输工作流用户任务待办ID。
    如何通过业务数据拿到工作流用户任务待办

  2. 界面设计器把这个字段拖到列表页里,并在跳转动作上配置上下文参数,把任务待办id传到表单页里。
    如何通过业务数据拿到工作流用户任务待办

  3. 重写教师模型的queryPage,通过业务数据id查询出每条业务数据的工作流用户任务待办id返回给前端。

    @Function.Advanced(displayName = "查询教师列表", type = FunctionTypeEnum.QUERY, category = FunctionCategoryEnum.QUERY_PAGE, managed = true)
    @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API})
    public Pagination<Teacher> queryPage(Pagination<Teacher> page, IWrapper<Teacher> queryWrapper) {
        Pagination<Teacher> teacherPagination = new Teacher().queryPage(page, queryWrapper);
        List<Teacher> content = teacherPagination.getContent();
        if (CollectionUtils.isEmpty(content)) {
            return teacherPagination;
        }
        List<Long> teacherIds = content.stream().map(Teacher::getId).collect(Collectors.toList());
        List<WorkflowUserTask> workflowUserTasks = Models.data().queryListByWrapper(Pops.<WorkflowUserTask>lambdaQuery()
                .from(WorkflowUserTask.MODEL_MODEL)
                .in(WorkflowUserTask::getNodeDataBizId, teacherIds)
                .orderByDesc(WorkflowUserTask::getCreateDate)
        );
        if (CollectionUtils.isEmpty(workflowUserTasks)) {
            return teacherPagination;
        }
        Map<Long/*业务id*/, WorkflowUserTask> userTaskMap = workflowUserTasks.stream().collect(Collectors.toMap(
                WorkflowUserTask::getNodeDataBizId, a -> a, (old, n) -> old)
        );
    
        for (Teacher teacher : content) {
            if (userTaskMap.containsKey(teacher.getId())) {
                teacher.setWorkflowUserTaskId(userTaskMap.get(teacher.getId()).getId());
            }
        }
        return teacherPagination;
    }
  4. 查看效果,任务待办id成功传到表单里面。
    如何通过业务数据拿到工作流用户任务待办

Oinone社区 作者:yexiu原创文章,如若转载,请注明出处:https://doc.oinone.top/other/20288.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

(0)
yexiu的头像yexiu数式员工
上一篇 2025年1月9日 pm8:38
下一篇 2025年1月16日 pm10:23

相关推荐

  • 设计器基础学习路径

    模块 内容 目标 doc 链接 模型设计器 模型 1.熟悉模型管理和字段管理 模型 数据字典 熟悉数据字典的创建 数据字典 数据编码 了解数据编码的操作创建 数据编码 界面设计器 了解页面 了解界面设计器中的页面 页面 页面设计 增删改查 【界面设计器】模型增删改查基础 页面设计 左树右表 【界面设计器】左树右表 页面设计 树形表格 【界面设计器】树形表格 页面设计 树下拉 【界面设计器】树下拉/级联 页面设计 自定义组件基础 【界面设计器】自定义字段组件基础 页面设计 熟悉页面设计的操作 页面设计 自定义组件 熟悉如何使用自定义组件 自定义组件 流程设计器 流程组成 了解流程的组成 流程 流程设计 熟悉流程设计内容 流程设计 熟悉流程的触发节点 流程触发 熟悉流程的节点动作与设计使用 节点动作 低代码与无代码结合 示例讲解 Outsourcing相关 低无一体的开发方式、设计数据的导入导出等

    2024年6月15日
    1.2K00
  • 自定义字段样式

    在日常开发中,我们经常会遇到需要根据业务规则动态展示字段样式的场景,比如表格、表单或详情中的某些字段需要改变文字颜色。本文将通过一个具体的案例,带大家实现这一功能。 以下以 自定义表格字段文字颜色 为例。 实现步骤 1. 在界面设计器中添加组件 通过界面设计器,添加一个组件 2. 创建元件 以表格的「金额字段」为例,创建对应的元件(可根据自己的业务场景调整)。 3. 配置元件属性 进入元件设计页面,从组件库中拖入「单行文本」到设计区域。在右侧属性面板中填写相关配置并保存 4. 保存元件 完成配置后,保存元件。 5. 发布元件 将元件发布,供页面设计使用。 6. 切换表格字段 进入页面设计器,将表格中的字段切换为刚刚创建的元件。 7. 配置字段颜色 在右侧属性面板中,配置字段的文字颜色: 固定颜色:直接输入颜色值(如 red)。 动态颜色:输入表达式,根据业务逻辑动态展示颜色。例如:当前行的名称等于 1 时显示红色,否则为蓝色。 示例表达式: activeRecord.name === '1' ? 'red' : 'blue' 8: 在代码中,自定义对应的表格字段 import { SPI, BaseFieldWidget, ModelFieldType, ViewType, TableCurrencyFieldWidget, Widget, RowContext, numberZeroFill, numberAddThousandth, Expression, ExpressionRunParam } from '@kunlun/dependencies'; import { toString } from 'lodash-es'; import { createVNode, VNode } from 'vue'; @SPI.ClassFactory( BaseFieldWidget.Token({ viewType: [ViewType.Table], ttype: [ModelFieldType.Currency], widget: 'TableCurrencyColor' }) ) export class TableCustomCurrencyFieldWidget extends TableCurrencyFieldWidget { computedFieldColor(context: RowContext) { const { fieldColor = ' ' } = this.getDsl(); if (!fieldColor) { return null; } // 如果当前颜色是表达式,则需要计算 if (Expression.hasKeywords(fieldColor)) { const params: ExpressionRunParam = { activeRecords: [context.data], rootRecord: {}, openerRecord: {}, scene: '' }; return Expression.run(params, fieldColor, fieldColor)!; } return fieldColor; } @Widget.Method() public renderDefaultSlot(context: RowContext): VNode[] | string { let value = numberZeroFill(toString(super.compute(context)), this.getPrecision(context)); if (this.getShowThousandth(context)) { value = numberAddThousandth(value); } return [ createVNode( 'div', { style: { color: this.computedFieldColor(context) } }, value ) ]; } } 9: 页面效果图

    2025年1月9日
    5.9K00
  • 前端学习路径

    准备工作 环境准备-1h安装基础环境,需要Node和PNPM如果已经安装检查对应版本,体验阶段建议版本保持一致 克隆一个空工程-0.5h全新工程 注意事项-0.5h静态资源解压,如果还没有对应的后端服务。可以使用:https://demo.oinone.top(Oinone演示环境),账号密码:admin/admin 前端基础 1.1.1了解组件-3h– 组件如何开发– 组件如何复用– 组件如何嵌套 1.1.2 更近一步-5h– 构建更复杂的工作台– 如何发起后端请求– 构建一个通用的图表组件 1.1.3 深入了解概念-5h– 通用概念、名词解释– 页面渲染原理– 组件执行原理 1.1.4业务实战-实现通用的甘特图组件-8h– 怎么与第三方结合– 如何在开源组件上接入Oinone, 并复用 1.1.5 业务实战-实现通用的画廊组件-6h–如何更近一步复用–基础学习结束 前端进阶 2.1.1代码和无代码如何结合-4h– 了解无代码如何使用和基础概念 2.1.2使用无代码搭建增删改查-8h– 了解无代码如何使用和基础概念 最后一步 当您实现玩基础和进阶的所有的效果,Oinone的整体使用您已经大致掌握了,接下来您可以找一个当前业务的场景来实现它把!

    2025年9月1日
    95600
  • 用户审批意见回填到审批表单

    需求 将审批同意时填写的审批意见以及图片回填到审批表单中。(填写节点同理) 实现方式一 通过审批后置函数操作流程参数的数据,并将流程参数数据回写到流程中。 流程设计 流程参数中自定义需要传递的字段。 审批节点设计审批后置函数,后置函数由后端定义。 添加更新数据节点,选择需要更新的业务表单字段,并在表达式中选择流程参数中自定义的字段。我这里更新审批意见和图片两个字段。 后置函数定义: /** * 审批后数据处理 * * @param approvalNode 审批节点 * @param context 上下文 * @param dataJson 审批提交数据 * @param result 审批结果 */ @Function(name = "approvalDataProcessFun", openLevel = API) @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "审批后数据处理", category = FunctionCategoryEnum.CUSTOM_DESIGNER) public void approvalDataProcessFun(ApprovalNode approvalNode, WorkflowContext context, String dataJson, Boolean result) { List<WorkflowUserTask> workflowUserTasks = Models.origin().queryListByWrapper(Pops.<WorkflowUserTask>lambdaQuery() .from(WorkflowUserTask.MODEL_MODEL) .eq(WorkflowUserTask::getTaskId, context.getLastTaskInstanceId()) ); // 获取审批意见等放入流程参数 for (WorkflowUserTask userTask : workflowUserTasks) { String remark = userTask.getRemark(); List<String> pics = userTask.getPics(); List<PamirsFile> attachments = userTask.getAttachments(); Map<String, Object> paramMap = (Map<String, Object>) context.getContext().getOrDefault(ParamNode.PARAM_PREFIX, new HashMap<String, Object>()); paramMap.put("remark", remark); paramMap.put("pics", pics); } } 实现方式二 通过审批动作(WorkflowUserTaskAction )扩展点实现 1、扩展点的定义 package pro.shushi.pamirs.work.core.extpoint; import pro.shushi.pamirs.meta.annotation.Ext; import pro.shushi.pamirs.meta.annotation.ExtPoint; import pro.shushi.pamirs.workflow.app.api.model.WorkflowUserTask; // @see:pro.shushi.pamirs.workflow.app.core.action.WorkflowUserTaskAction /** * Oinone所有的函数都提供了默认的前置扩展点、重载扩展点和后置扩展点, * 其技术名称的规则是所扩展函数的函数编码fun加上“Before”、“Override”和“After”后缀 * * 根据实际情况保留扩展点的接口和实现(可增加、可删减) */ @Ext(WorkflowUserTask.class) public interface WorkflowUserTaskDealExtPoint { // 实际需要几个扩展点根据业务情况自行 增加 和 删除 @ExtPoint(displayName = "审批同意后") WorkflowUserTask approveAgreeAfter(WorkflowUserTask workflowUserTask); @ExtPoint(displayName = "审批撤销后") WorkflowUserTask recallAfter(WorkflowUserTask workflowUserTask); @ExtPoint(displayName = "审批转审后") WorkflowUserTask approveTrangerAfter(WorkflowUserTask workflowUserTask); @ExtPoint(displayName = "审批转审前") WorkflowUserTask approveFallbackBefore(WorkflowUserTask workflowUserTask); @ExtPoint(displayName = "审批拒绝后") WorkflowUserTask approveRejustAfter(WorkflowUserTask workflowUserTask); @ExtPoint(displayName = "审批转审后") WorkflowUserTask approveFallbackAfter(WorkflowUserTask workflowUserTask); // ………… } 2、扩展点的实现 package pro.shushi.pamirs.work.core.extpoint; import org.springframework.stereotype.Component; import pro.shushi.pamirs.meta.annotation.Ext; import…

    2026年2月10日
    19700
  • 前端自定义组件之锚点分组

    本文将讲解如何通过自定义,实现锚点组件。这个锚点组件会根据界面设计器拖入的分组,动态解析出锚点。 实现路径 整体的实现思路是界面设计器拖个容器类的组件(这里以选项卡为例),自定义这个选项卡,往选项卡里拖拽的每个分组,每个锚点的名称是分组的标题。 1. 界面设计器拖出页面 我们界面设计器拖个选项卡组件,然后在选项页里拖拽任意多个分组。完成后点击右上角九宫格,选中选项卡,填入组件 api 名称,作用是把选项卡切换成我们自定义的锚点分组组件,这里的 api 名称和自定义组件的 widget 对应。最后发布页面,并绑定菜单。 2. 组件实现 widget 组件重写了选项卡,核心函数 renderGroups,通过 DslRender.render 方法渲染界面设计器拖拽的分组。 import { BasePackWidget, DslDefinition, DslRender, SPI, Widget } from '@oinone/kunlun-dependencies'; import TabsParseGroup from './TabsParseGroup.vue'; function fetchGroupChildren(widgets?: DslDefinition[], level = 1): DslDefinition[] { if (!widgets) { return []; } const children: DslDefinition[] = []; for (const widget of widgets) { if (widget.widget === 'group') { children.push(widget); } else if (level >= 1) { fetchGroupChildren(widget.widgets, level – 1).forEach((child) => children.push(child)); } } return children; } @SPI.ClassFactory( BasePackWidget.Token({ widget: 'TabsParseGroup' }) ) export class TabsParseGroupWidget extends BasePackWidget { public initialize(props) { super.initialize(props); this.setComponent(TabsParseGroup); return this; } // 获取分组的子元素 public get groupChildren(): DslDefinition[] { return fetchGroupChildren(this.template?.widgets); } @Widget.Reactive() public get groupTitles() { return this.groupChildren.map((group) => group.title); } // 根据容器子元素渲染左侧 @Widget.Method() public renderGroups() { if (this.groupChildren && this.groupChildren.length) { return this.groupChildren.map((group) => DslRender.render(group)); } } } vue组件核心内容是用component :is属性,渲染出配置的分组组件 <template> <div class="TabsParseGroup"> <a-anchor :affix="false"> <a-anchor-link v-for="(item, index) in groupTitles" :href="`#default-group-${index}`" :title="item" /> </a-anchor> <div v-for="(item, index) in groupComponents" :id="`default-group-${index}`"> <component :is="item" /> </div> </div> </template> <script lang="ts"> import { computed, defineComponent, PropType } from 'vue'; export default…

    2025年7月8日
    41000

Leave a Reply

登录后才能评论