【工作流】流程扩展自定义函数示例代码汇总

目录

1. 流程节点审批人函数
2. 审批开始前执行函数
3. 填写执行前执行函数
4. 待办操作提交后执行函数
5. 审批操作数据函数
6. 自定义通知人函数

1. 流程节点审批人函数

包含转交、抄送、加签、填写、通知人自定义函数
当平台默认提供的审批人选择无法满足个性化的业务需求时,我们可以通过自定义函数处理审批人的生成逻辑

1.1 编写自定义审批人函数

    @Function(openLevel = {FunctionOpenEnum.API})
    @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "报销单-证明人-审批", category = CUSTOM_DESIGNER)
    public List<NodePerson> bizZmrApprovePerson(List<NodePerson> nodePersonList, NodeModel nodeModel, WorkflowContext workflowContext) {
        List<NodePerson> newNodePersonList = new ArrayList<>();
        String nodeModelId = nodeModel.getId();
        Object nodeData = workflowContext.get(nodeModelId);
        BuissModel inputBuissModel = JsonUtils.parseObject(JsonUtils.toJSONString(nodeData), BUISSMODEL_TR);
        BuissModel buissModel = new BuissModel().setId(inputBuissModel.getId()).queryById();
        buissModel.fieldQuery(BuissModel::getZmEmployee);
        BxEmployee zmEmployee = buissModel.getZmEmployee();
        if (zmEmployee == null) {
            log.error("报销单ID:{},名称:{}, 获取证明人为空", buissModel.getId(), buissModel.getName());
            return newNodePersonList;
        }
        NodePersonUser personUser = new NodePersonUser();
        List<NodePersonUser> nodePersonUsers = new ArrayList<>();
        NodePerson person = new NodePerson();
        person.setId(zmEmployee.getBindingUserId() + "");
        person.setType(NodePersonTypeEnum.USER);
        personUser.setUserId(zmEmployee.getBindingUserId());
        nodePersonUsers.add(personUser);
        person.setNodePersonUsers(nodePersonUsers);
        newNodePersonList.add(person);

        return newNodePersonList;
    }

1.2 流程设计器的审批节点设置自定义函数

【工作流】流程扩展自定义函数示例代码汇总

2.审批开始前执行函数

使用场景:在流程执行到审批或填写节点任务初始化后,任务尚未开始,需要在初始化任务做一些自定义逻辑处理时,使用该扩展
执行时间:执行节点是在审批或填写待办任务初始化之后,审批或填写结果执行之前,执行该扩展

/**
 * 审批节点初始化完成,执行前置函数
 * @param approvalNode
 * @param context
 * @param taskInstance
 */
@Function(name = "approvalCustomStartFun",openLevel = FunctionOpenEnum.API)
@Function.Advanced(type= FunctionTypeEnum.QUERY,displayName = "审批执行前置处理",category = FunctionCategoryEnum.CUSTOM_DESIGNER )
public void approvalCustomStartFun(ApprovalNode approvalNode, WorkflowContext context, WorkflowTaskInstance taskInstance) {
    // TODO: 2024/2/23 可以根据结果自己处理业务逻辑
}

3.填写执行前执行函数

    /**
     * 填写执行前置处理
     */
    @Function(name = "writeCustomStartFun", openLevel = FunctionOpenEnum.API)
    @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "填写执行前置处理", category = FunctionCategoryEnum.CUSTOM_DESIGNER)
    public void writeCustomStartFun(WorkflowTaskInstance taskInstance, WriteNode writeNode, WorkflowContext context) {
        System.out.println("填写执行前置处理");
    }

4. 待办操作提交后执行函数

使用场景:在审批或填写的待办任务在操作任务时,需要额外执行一些逻辑,比如当前人提交操作以后需要更新更当前人操作相关的数据库记录,
执行时间:执行节点是在保存待办任务之后,异步执行审批或填写结果之前,执行该扩展

/**
 * 转交操作后置函数,再流程设计器中审批和填写节点中 扩展设置-填写操作提交后执行函数选择
 * @param userTask 用户待办记录
 * @return 待办记录
 */
@Function(name = "transformOrgSelectEndFun",openLevel = FunctionOpenEnum.API)
@Function.Advanced(type= FunctionTypeEnum.QUERY,displayName = "转交操作后置函数",category = FunctionCategoryEnum.CUSTOM_DESIGNER )
public WorkflowUserTask transformOrgSelectEndFun(WorkflowUserTask userTask) {
    //可针对操作类型进行过滤
    // 转交操作后
    if (!WorkflowUserTaskOperateTypeEnum.APPROVE_TRANGER.equals(userTask.getOperateType())) {
        return userTask;
    }
    // TODO: 2023/11/21 可自定义补充业务逻辑 userTask对应中数据为本次提交T的数据

    // 审批同意的情况下
    if (WorkflowUserTaskOperateTypeEnum.APPROVE_AGREE.equals(userTask.getOperateType())) {
        // TODO
    }

    // 审批拒绝的情况下
    if (WorkflowUserTaskOperateTypeEnum.APPROVE_REJUST.equals(userTask.getOperateType())) {
        // TODO
    }

    return userTask;
}

5.审批操作数据函数

使用场景:在审批或填写执行过程中审批同意或则填写提交时,需要额外更改其他的业务数据逻辑,如审批同意后需要修改关联数据状态之类
执行时间:在审批或填写执行过程中审批同意或则填写提交后执行完业务数据保存后,执行该扩展

/**
 * 审批后数据处理
 * @param approvalNode 审批节点
 * @param context 上下文
 * @param dataJson 审批提交数据
 * @param result 审批结果
 */
@Function(name = "approvalDataProcessFun",openLevel = FunctionOpenEnum.API)
@Function.Advanced(type= FunctionTypeEnum.QUERY,displayName = "审批后数据处理",category = FunctionCategoryEnum.CUSTOM_DESIGNER )
public void approvalDataProcessFun(ApprovalNode approvalNode, WorkflowContext context, String dataJson, Boolean result) {
    //审批数据提交数据内容
    Map<String, Object> data = JsonUtils.parseMap(dataJson);
    Long id = ParamUtils.createLong(data.get("id"));
    //可根据审批结果来处理自定义数据--通过
    if(result != null && result){
        // TODO: 2024/2/23 可以根据结果自己处理业务逻辑
    }

    //拒绝
    if(result != null && !result){
        // TODO: 2024/2/23 可以根据结果自己处理业务逻辑
    }
}

6.自定义通知人函数

使用场景:在站内信等通知节点选择的自定人通知人函数。

@Function(openLevel = FunctionOpenEnum.API)
@Function.Advanced(displayName = "调用自定义通知人函数", category = FunctionCategoryEnum.CUSTOM_DESIGNER)
public List<NodePerson> sendCustomNotifications(List<NodePerson> nodePerson, NodeModel personModel, WorkflowContext context) {
    // 获取表单数据。
    Map<String, Object> formData = context.getContext();
    Object obj = formData.get(personModel.getId());
    Map<String, Object> data = null;
    if (obj instanceof Map) {
        data = (Map<String, Object>) obj;
    }
    // 可根据业务逻辑自行处理。
    if (data == null) {
        return nodePerson;
    }
    String login = data.get("login").toString();
    PamirsUser user = new PamirsUser().setLogin(login).queryOne();
    List<NodePerson> newPerson = new ArrayList<>();
    NodePerson person = new NodePerson();
    person.setId(user.getId() + "");
    person.setType(NodePersonTypeEnum.USER);
    person.setName(user.getName());
    newPerson.add(person);
    return newPerson;
}

Oinone社区 作者:nation原创文章,如若转载,请注明出处:https://doc.oinone.top/designer/workflowdesigner/4802.html

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

(0)
nation的头像nation数式员工
上一篇 2023年12月1日 am11:38
下一篇 2023年12月4日 pm8:49

相关推荐

  • 项目中工作流引入和流程触发

    目录 1. 使用工作流需要依赖的包和设置2. 触发方式2.1 自动触发方式2.2 触发方式 1.使用工作流需要依赖的包和设置 1.1 工作流需要依赖的模块 需在pom.xml中增加workflow、sql-record和trigger相关模块的依赖 workflow:工作流运行核心模块 sql-record:监听流程发布以后对应模型的增删改监听 trigger:异步任务调度模块 <dependency> <groupId>pro.shushi.pamirs.workflow</groupId> <artifactId>pamirs-workflow-api</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.workflow</groupId> <artifactId>pamirs-workflow-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-sql-record-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-bridge-tbschedule</artifactId> </dependency> 在application.yml中增加对应模块的依赖以及sql-record路径以及其他相关设置 pamirs: … record: sql: #改成自己路径 store: /opt/pamirs/logs … boot: init: true sync: true modules: … – sql_record – trigger – workflow … sharding: define: data-sources: ds: pamirs models: "[trigger.PamirsSchedule]": tables: 0..13 event: enabled: true schedule: enabled: true # ownSign区分不同应用 ownSign: demo rocket-mq: # enabled 为 false情况不用配置 namesrv-addr: 192.168.6.2:19876 trigger: auto-trigger: true 2.触发方式 2.1自动触发方式 在流程设计器中设置触发方式,如果设置了代码触发方式则不会自动触发 2.2代码调用方式触发 2.2.1.再流程设计器中触发设置中,设置为是否人工触发设置为是 2.2.2.查询数据库获取该流程的编码 2.2.3.在代码中调用 /** * 触发⼯作流实例 */ private Boolean startWorkflow(WorkflowD workflowD, IdModel modelData) { WorkflowDefinition workflowDefinition = new WorkflowDefinition().queryOneByWrapper( Pops.<WorkflowDefinition>lambdaQuery() .from(WorkflowDefinition.MODEL_MODEL) .eq(WorkflowDefinition::getWorkflowCode, workflowD.getCode()) .eq(WorkflowDefinition::getActive, 1) ); if (null == workflowDefinition) { // 流程没有运⾏实例 return Boolean.FALSE; } String model = Models.api().getModel(modelData); //⼯作流上下⽂ WorkflowDataContext wdc = new WorkflowDataContext(); wdc.setDataType(WorkflowVariationTypeEnum.ADD); wdc.setModel(model); wdc.setWorkflowDefinitionDefinition(workflowDefinition.parseContent()); wdc.setWorkflowDefinition(workflowDefinition); wdc.setWorkflowDefinitionId(workflowDefinition.getId()); IdModel copyData = KryoUtils.get().copy(modelData); // ⼿动触发创建的动作流,将操作⼈设置为当前⽤户,作为流程的发起⼈ copyData.setCreateUid(PamirsSession.getUserId()); copyData.setWriteUid(PamirsSession.getUserId()); String jsonData = JsonUtils.toJSONString(copyData.get_d()); //触发⼯作流 新增时触发-onCreateManual 更新时触发-onUpdateManual Fun.run(WorkflowModelTriggerFunction.FUN_NAMESPACE, "onCreateManual", wdc, msgId, jsonData); return Boolean.TRUE; }

    2023年11月7日
    1.1K00
  • 【工作流】如何添加工作流运行时依赖

    前端 package.json中新增依赖 @kunlun/workflow,版本跟@kunlun/dependencies的填一样 src/main.ts内导入依赖 import 'reflect-metadata'; import { VueOioProvider } from '@kunlun/dependencies'; // START 导入代码放在导入@kunlun/dependencies之后 import '@kunlun/workflow/dist/kunlun-workflow.css'; import '@kunlun/workflow'; // END 导入代码放在VueOioProvider()方法执行前 VueOioProvider({ // TODO }); 后端 父pom新增依赖,下面例子中的版本号仅供参考,请根据当前框架版本正确选择版本 <properties> <pamirs.core.version>4.7.8</pamirs.core.version> <pamirs.workflow.designer.version>4.7.8</pamirs.workflow.designer.version> <pamirs.workbench.version>4.7.8</pamirs.workbench.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-core-dependencies</artifactId> <version>${pamirs.core.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <artifactId>pamirs-workflow</artifactId> <version>${pamirs.workflow.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>pro.shushi.pamirs.work.bench</groupId> <artifactId>pamirs-work-bench-core</artifactId> <version>${pamirs.workbench.version}</version> </dependency> <dependency> <groupId>pro.shushi.pamirs.work.bench</groupId> <artifactId>pamirs-work-bench-view</artifactId> <version>${pamirs.workbench.version}</version> </dependency> </dependencies> </dependencyManagement> 2.boot启动工程的pom新增依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-sql-record-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-bridge-tbschedule</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-user-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-user-view</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-auth-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-business-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-business-view</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.workflow</groupId> <artifactId>pamirs-workflow-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.work.bench</groupId> <artifactId>pamirs-work-bench-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.work.bench</groupId> <artifactId>pamirs-work-bench-view</artifactId> </dependency> 3.application.yml配置新增依赖 pamirs: boot: modules: – user – auth – business – sql_record – trigger – workflow 特别注意 工作流模块如果线上部署需要流程设计器能力,可以参考文档流程设计器部署注意事项

    2024年5月30日
    1.1K00
  • 【工作流】如何自定义工作流的待办任务列表

    介绍 有些时候我们需要把一些业务数据同时展示在工作流的待办列表中,这时候我们可以通过覆写oinone的待办列表展示组件 1.添加工作流相关依赖 业务的api工程添加工作流相关依赖 package pro.shushi.pamirs.demo.api; import org.springframework.stereotype.Component; import pro.shushi.pamirs.core.common.CommonModule; import pro.shushi.pamirs.file.api.FileModule; import pro.shushi.pamirs.meta.annotation.Module; import pro.shushi.pamirs.meta.base.PamirsModule; import pro.shushi.pamirs.meta.common.constants.ModuleConstants; import pro.shushi.pamirs.user.api.UserModule; import pro.shushi.pamirs.workflow.app.api.WorkflowModule; @Component @Module( name = DemoModule.MODULE_NAME, displayName = "oinoneDemo工程", version = "1.0.0", // 登录后默认访问 priority 值最小的模块 priority = 1, dependencies = {ModuleConstants.MODULE_BASE, CommonModule.MODULE_MODULE, UserModule.MODULE_MODULE, // 此处新增工作流依赖 WorkflowModule.MODULE_MODULE, FileModule.MODULE_MODULE } ) @Module.module(DemoModule.MODULE_MODULE) @Module.Advanced(selfBuilt = true, application = true) public class DemoModule implements PamirsModule { public static final String MODULE_MODULE = "demo_core"; public static final String MODULE_NAME = "DemoCore"; @Override public String[] packagePrefix() { return new String[]{ "pro.shushi.pamirs.demo" }; } } 业务的core工程添加工作流相关依赖 <dependency> <groupId>pro.shushi.pamirs.workflow</groupId> <artifactId>pamirs-workflow-api</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.workflow</groupId> <artifactId>pamirs-workflow-core</artifactId> </dependency> 2. 由于平台原有的视图中未返回业务模型的原始数据的字段,所以我们先要将originNodeContext字段加到视图中,该workbench_usertask_active_table.xml文件存放在src/resources目录下 <view model="workbench.WorkBenchWorkflowUserTaskActive" type="gallery" viewName="全部待办" name="全部待办" title="全部待办" layout="workflow_gallery_layout"> <template slot="search" widget="search" disabledExpand="true" invisibleSearch="true"> <field allowClear="true" span="4" widget="TabSelect" data="optionSelect" label="false" required="false" defaultValue="ACTIVE_TOTAl"/> <field allowClear="true" span="2" widget="TagSelect" data="taskTypeSelect" label="false" required="false" defaultValue="TOTAL"/> <field allowClear="true" span="1" name="workflowModule" data="workflowModule" label="false" placeholder="所属应用" searchTrigger="change" domain="systemSource != 'BASE' and systemSource != 'SYSTEM' and state=='installed' and application=='true' " /> <field allowClear="true" span="1" widget="SearchInput" data="name" label="false" placeholder="使用名称搜索" required="false"/> </template> <template slot="actionBar" widget="actionBar"/> <template colSpan="FULL" cols="1" defaultPageSize="OPTION_3" disabled="false" gotoListExportDialog="false" gotoListImportDialog="false" invisible="false" readonly="false" required="false" slot="gallery" widget="workflow-gallery"> <template area="title,content,rowActions" colSpan="FULL" disabled="false" inlineActiveCount="FIVE" invisible="false"…

    2024年5月8日
    1.0K00
  • 自定义流程设计器审批人公司列表

    打开弹窗时会默认选中返回的第一个公司。 依赖: <dependency> <groupId>pro.shushi.pamirs.workflow</groupId> <artifactId>pamirs-workflow-api</artifactId> </dependency> 只显示所有公司 ALL_COMPANY 表示所有公司。 @Order(10) @Component @SPI.Service public class CustomWorkflowCompanyQueryApi implements WorkflowCompanyQueryApi { @Override public Pagination<PamirsCompany> queryPage(Pagination<PamirsCompany> page, IWrapper<PamirsCompany> queryWrapper) { Pagination<PamirsCompany> pageResult = new Pagination<>(); pageResult.setContent(Lists.newArrayList(ALL_COMPANY)); pageResult.setTotalPages(1); return pageResult; } } 不显示所有公司 @Order(10) @Component @SPI.Service public class CustomWorkflowCompanyQueryApi implements WorkflowCompanyQueryApi { @Override public Pagination<PamirsCompany> queryPage(Pagination<PamirsCompany> page, IWrapper<PamirsCompany> queryWrapper) { return new PamirsCompany().queryPage(page, queryWrapper); } } 仅显示特定公司 @Order(10) @Component @SPI.Service public class CustomWorkflowCompanyQueryApi implements WorkflowCompanyQueryApi { private static final Set<String> COMPANY_CODES = Sets.newHashSet("CH0001", "CH0002"); @Override public Pagination<PamirsCompany> queryPage(Pagination<PamirsCompany> page, IWrapper<PamirsCompany> queryWrapper) { Set<String> companyCodes = Sets.newHashSet("CH0001", "CH0002"); LambdaQueryWrapper<PamirsCompany> query = ((QueryWrapper<PamirsCompany>) queryWrapper).lambda(); query.in(PamirsCompany::getCode, COMPANY_CODES); return new PamirsCompany().queryPage(page, queryWrapper); } }

    2025年9月4日
    74100
  • 【工作流】如何在业务模型的列表中展示工作流的审批按钮

    介绍 当我们需要在业务模型的列表中展示审批的按钮时,我们可以通过自定义的方式完成扩展,这样就可以在业务数据中直接点击该动作按钮跳转到工作流待办详情页处理审批或填写任务 1.先在业务数据模型中新增userTaskList字段存放该条数据的工作流待办数据 @Model.model(DemoItem.MODEL_MODEL) @Model(displayName = "测试商品") public class DemoItem extends IdModel { @Field.one2many @Field(displayName = "工作流任务列表", store = NullableBoolEnum.FALSE, invisible = true) @Field.Relation(store = false) private List<WorkflowUserTask> userTaskList; } 2. 在业务数据的查询方法中查询当前登录用户在工作流任务中的数据 @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "查询列表", 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; } 3. 在界面设计器拖一个服务端动作到操作列中 4. 将工作流任务列表字段userTaskList拖到表格列中并隐藏该字段 5. 前端自定义跳转到工作流待办详情页的动作组件 import { ActionType, ActionWidget, ClickResult, executeViewAction, RuntimeViewAction, ServerActionWidget, SPI, ViewActionTarget, ViewType, Widget } from '@kunlun/dependencies'; // name为界面设计器拖出的动作名称 @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…

    2024年5月8日
    1.4K00

Leave a Reply

登录后才能评论