登录
文档目录
图片名称

流程设计前端数据结构

一、流程属性

1. 基础属性

参数名称

类型

说明

workflowCode

string

流程编码

workflowName

string

显示名称


2. 流程事件

参数名称

类型

说明

startEventHandler

ActivityEventHandler | null

流程启动事件

endEventHandler

ActivityEventHandler | null

流程结束事件

cancelEventHandler

ActivityEventHandler | null

流程作废事件

activateEventHandler

ActivityEventHandler | null

流程激活事件


ActivityEventHandler 类型

参数名称

类型

说明

bizActions

Array

执行业务方法

content

string

通知消息内容

dataDisposals

Array

设置数据,
[{
property: string,  // 数据项
disposalType: string, // 操作方法
value: string // 设置值
}]

popupType

string

参与者函数弹窗类型(EXPRESSION:表达式视图,FUNCTION:公式视图)

receiver

string

钉钉消息通知方(参与者函数公式)

cancelParllelActivity

boolean

是否取消并行活动(节点特有)

rejectCancelParllelActivity

boolean

驳回是否取消并行活动(节点特有)

二、节点属性(activity)

1. 一般属性

参数名称

类型

说明

activityCode

string

编码

activityName

string

显示名称

name_i18n

object

显示名称国际化字段

activityType

string

节点类型

sheetCode

string

任务表单(传阅、用户活动特有)

todoDataItem.dataItemType

number

消息通知(用户活动特有)

todoDataItem.summary

string

自定义通知内容

todoDataItem.title

String

自定义通知标题

sync

boolean

子流程启动方式(子流程特有)

workflowCode

string

子流程模板(子流程特有)

finishStartActivity

boolean

发起环节是否自动提交(子流程特有)

triggerMappingObj

object

触发对象(子流程特有):
{
mainTable:  number, // (0: 主表,1:子表)
code: string  // 子表编码
}


2. 参与者

参数名称

类型

说明

participant

string

参与者,(参与者函数公式)

popupType

string

参与者函数弹窗类型(EXPRESSION:表达式视图,FUNCTION:公式视图)

participationModel

string

参与者类型:多人 / 单人

noParticipant

string

无参与者:转交管理员 / 直接通过

originator

string

参与者是发起人,是否直接通过

perviousParticipate

string

参与者在前一活动处理过,是否直接通过

participated

string

参与者处理过流程,是否直接通过


3. 数据权限(propertyPermissions)


数据项权限 Item 元数据:

参数名称

类型

说明

propertyName

string

数据项名称

propertyCode

string

数据项编码

editable

boolean

是否可写

visible

boolean

是否可见

required

boolean

是否必填

propertyEmpty

boolean

是否允许为空

subPropertyPermissions

Array

子表数据权限


4. 操作权限(permittedAction)

参数名称

类型

说明

forward

boolean

是否允许转办

retrieve

boolean

是否允许撤回

assist

boolean

是否允许协办

circulate

boolean

是否允许传阅

adjustParticipant

boolean

是否允许加签

finishInstance

boolean

是否直接结束流程

reject

boolean

是否允许驳回到上一步

rejectToStart

boolean

是否允许驳回到开始节点

rejectToFixded

boolean

是否允许驳回到指定活动

rejectToActivityCode

string

驳回到指定节点对应的节点编码


5. 高级

参数名称

类型

说明

allowedTime

string

限时时间

timeoutWarning1

string

超时预警1

timeoutWarning2

string

超时预警2

timeoutStrategy

string

超时策略


6. 事件处理

参数名称

类型

说明

beforeActivate

ActivityEventHandler

活动激活前

afterActivate

ActivityEventHandler

活动激活后

endActivity

ActivityEventHandler

活动完成后

cancelActivity

ActivityEventHandler

活动取消后

三、连接线属性(rules)

参数名称

类型

说明

text

string | null

显示名称

name_i18n

string

显示名称国际化:{"en":""}

formula

string

条件设置

popupType

string

参与者函数弹窗类型(EXPRESSION:表达式视图,FUNCTION:公式视图)

utilizeElse

boolean

是否使用else

preActivityCode

string

接入节点编码

postActivityCode

string

流出节点编码

points

Array

线上折点:["x,y"],eg: ["406,76"]


需求概述

流程设计中新增加节点"用户活动(密级)",该节点的属性栏中只显示四个属性,节点名称,节点编码,参与人与密级。流程运转到该节点进行参与人计算时,需要根据节点上的密级属性配置与计算出的参与人密级字段进行二次过滤。

(人员密级信息由人员拓展字段提供数据)

前端扩展说明

一、节点扩展配置

扩展路径:packages\extension-template\src\workflow-design\extension-activities.ts

节点配置示例

import { ActivityTypes } from 'cloudpivot-admin-core/src/common/workflow-schema/typings/enums';

/**
 * 扩展节点
 */
interface ExtActivity {
  //节点中文名称
  activityName: string;
  //节点类型(继承自)
  activityType: ActivityTypes;
  //扩展节点类型(节点根据节点类型定位属性栏配置时,优先取扩展节点类型,其次才是节点类型)
  extendActivityType: string;
  //后端要求扩展属性得放在节点对象的属性extAttributes对象中,这里定义extAttributes对象的属性初始值
  extAttributes: any;
  // 节点图标,使用iconfont图标库,标识图标的unicode编码。如:
  // 云枢图标库demo文件地址:packages\builtin\cloudpivot-icons\src\demo_index.html;浏览器打开查看图标
  icon?: string;
  // 节点名称多语言对象
  name_i18n?: {
    en: string; 
  },
}

/**
 * 扩展节点数组
 */
export const extActivities: ExtActivity[] = [
  {
    activityName: '用户活动(密级)',
    activityType: ActivityTypes.User,
    extendActivityType: 'CustomNode',
    extAttributes: {
      securityLevel: '0',
    },
  },
];

ExtActivity扩展节点对象中的可选属性若不进行定义,则跟继承的系统节点类型保持一致,例如:icon、name_i18n

注:extendActivityType项目已经使用,相关字段需前后端同步修改

节点配置后运行效果

节点扩展配置完成后,会在流程设计左侧流程节点列表中增加一个扩展节点,此时还需要给节点配置相关属性

二、节点属性面板配置

扩展路径:packages\extension-template\src\workflow-design\attr-panel\extension-panel-example.ts

引用产品已定义属性

产品已定义的流程节点属性,可直接引用,例如:activityCode、activityName、participant等;

获取方式:attrPanelRegister.getAttr(节点类型, 属性code),例如:attrPanelRegister.getAttr(ActivityTypes.User, 'activityCode')

属性配置示例

import { PanelConfig } from 'cloudpivot-designer/property-panel';
import { attrPanelRegister } from 'cloudpivot-admin-core/src/components/apps/workflow-property/scripts';
import { ActivityTypes } from 'cloudpivot-admin-core/src/common/workflow-schema/typings/enums';

const panelExample: PanelConfig = {
  properties: [
    attrPanelRegister.getAttr(ActivityTypes.User, 'activityCode'),
    attrPanelRegister.getAttr(ActivityTypes.User, 'activityName'),
    attrPanelRegister.getAttr(ActivityTypes.User, 'participant'),
    {
      title: '密级',
      code: 'securityLevel',
      //输入组件名称
      inputComponentName: 'property-select',
      //输入组件的参数
      options: {
        selectOptions: [
          { label: '非密', value: '0' },
          { label: '内部', value: '1' },
          { label: '秘密', value: '2' },
          { label: '机密', value: '3' },
          { label: '绝密', value: '4' },
        ],
      },
      /**
       * 用户修改密级字段信息时,同步修改节点对象中扩展对象extAttributes下securityLevel属性的值
       **/
      valueMap: 'extAttributes.securityLevel',
    }
  ],
};

export default panelExample;

三、节点属性面板注册

扩展路径:packages\extension-template\src\workflow-design\extension-attr-panel.ts

import { attrPanelRegister } from 'cloudpivot-admin-core/src/components/apps/workflow-property/scripts';

import panelExample from './attr-panel/extend-panel-example';

attrPanelRegister.append('CustomNode', panelExample);

注册后运行效果

后端扩展说明

扩展示例代码

public class ExtParticipantFilterServiceImpl implements ParticipantFilterService {
    // autowires
    private UserFacade userFacade;
    private UserExtendFacade userExtendFacade;

    @Override
    public Set<String> doFilter(Set<String> participants, ParticipantProcessorContext context) {
        if (CollectionUtils.isEmpty(participants)) {
            return participants;
        }
        ConfidentialLevel confidentialLevel = getConfidentialLevel(context);
        if (confidentialLevel == null || confidentialLevel == ConfidentialLevel.NON_CONFIDENTIAL) {
            return participants;
        }
        List<String> userIdList = Lists.newArrayList(participants);
        List<UserModel> userModels = userFacade.listByIdList(userIdList);
        if (CollectionUtils.isEmpty(userModels)) {
            return participants;
        }
        UserExtAttrModel confidentialLevelAttr = userExtendFacade.getExtAttrByCorpIdAndCode("RELEVANCE-6cf4718787374570a0c583f939077e77", "confidentialLevel");
        if (confidentialLevelAttr == null) {
            return participants;
        }
        Set<String> filtered = Sets.newLinkedHashSet();
        List<UserUnionExtAttrModel> extAttrs = userExtendFacade.listUnionByUserIdListAndAttrIdList(userIdList, Lists.newArrayList(confidentialLevelAttr.getId()));
        if (CollectionUtils.isEmpty(extAttrs)) {
            return filtered;
        }
        Map<String, List<UserUnionExtAttrModel>> userId2ExtAttrs = extAttrs.stream().collect(Collectors.groupingBy(UserUnionExtAttrModel::getUserId));
        for (UserModel userModel : userModels) {
            List<UserUnionExtAttrModel> userExtAttrs = userId2ExtAttrs.get(userModel.getId());
            if (CollectionUtils.isEmpty(userExtAttrs)) {
                continue;
            }
            if (userExtAttrs.stream().anyMatch(e -> {
                ConfidentialLevel level = ConfidentialLevel.get(e.getMapVal());
                return level != null && level.getIndex() >= confidentialLevel.getIndex();
            })) {
                filtered.add(userModel.getId());
            }
        }
        return filtered;
    }

    private ConfidentialLevel getConfidentialLevel(ParticipantProcessorContext context) {
        Map<String, Object> extAttributes = context.getActivity().getExtAttributes();
        if (MapUtils.isEmpty(extAttributes)) {
            return ConfidentialLevel.NON_CONFIDENTIAL;
        }
        String securityLevel = (String) extAttributes.get("securityLevel");
        if (StringUtils.isBlank(securityLevel)) {
            return ConfidentialLevel.NON_CONFIDENTIAL;
        }
        return ConfidentialLevel.get(Integer.parseInt(securityLevel));
    }

    public enum ConfidentialLevel {
        /**
         * 非密、内部、秘密、机密、绝密
         */
        NON_CONFIDENTIAL("非密", 0),
        INTERNAL("内部", 1),
        CONFIDENTIAL("秘密", 2),
        SECRET("机密", 3),
        TOP_SECRET("绝密", 4);

        private final String name;
        private final int index;

        ConfidentialLevel(String name, int index) {
            this.name = name;
            this.index = index;
        }

        public static ConfidentialLevel get(int index) {
            for (ConfidentialLevel level : values()) {
                if (level.index == index) {
                    return level;
                }
            }
            return null;
        }

        public static ConfidentialLevel get(String name) {
            for (ConfidentialLevel level : values()) {
                if (StringUtils.equals(level.name, name)) {
                    return level;
                }
            }
            return null;
        }

        // getters..
    }
}

二次开发效果截图

表单详情

用户配置

Q&A

使用到的二开扩展能力

  1. 前端流程设计-流程节点扩展开发说明文档

此处为语雀内容卡片,点击链接查看:https://www.yuque.com/skwme4/hzo079/xqgpwg6mphobtgsq
  1. 前端流程设计-流程节点属性栏配置扩展开发说明文档

此处为语雀内容卡片,点击链接查看:https://www.yuque.com/skwme4/hzo079/hcfhccl86dv8p6ey
  1. 后端流程运行参与人函数扩展

流程属性栏注册器API

方法名称

说明

参数说明

append(panelCode: string, panelConfig: PanelConfig)

添加新的属性栏配置

属性栏code,属性栏配置

replace(panelCode: string, panelConfig: PanelConfig)

替换现有的属性栏配置

属性栏code,属性栏配置

replaceAttr(panelCode: string, attrConfig: PropertySchema)

替换现有属性栏中的某个属性

属性栏code,属性配置(包含属性的code)

appendAttr(panelCode: string, attrConfig: PropertySchema, groupKey?: string)

在现有属性栏中追加新属性,分组编码可选,如果不传入分组编码则在最后一个分组中添加

属性栏code, 属性配置,分组编码

appendGroup(panelCode: string, groupInfo: any)

在现有属性栏中添加分组

属性栏code,分组信息

getAttr(panelCode: string, attrCode: string)

获取现有的属性栏中,某个属性的具体配置

属性栏code, 属性code

属性配置properties释义

interface PropertySchema {
  //属性标题,如果不设置则表示不需要显示标题
  title?: string;
  //属性编码
  code: string;
  /**
   * 输入组件值的映射,如果只是简单通过code取可以不设置,如果是多个属性合并的场景,需要配置
   * 例如:code为a,b,c,valueMap为['a','b','c'],则输入组件的值为{a:1,b:2,c:3}
   **/
  valueMap?: string[] | any;
  //属性提示
  tips?: string;
  //输入组件名称
  inputComponentName: string;
  // 自定义的判空逻辑,如果不设置则默认为!!value
  isNotEmpty?: (value: any) => boolean;
  // 自定义的必填提示文案,如果不设置走默认文案逻辑
  getRequiredErrorMessage?: (controller, propertiesData) => string;
  // 必填以外的校验逻辑,校验后的提示文案
  getValueValidateErrorMessage?: (controller, propertiesData) => string;
  //默认值函数
  defaultValue?: (businessContext, propertiesData: any) => any;
  //弹窗组件是否需要显示删除确认弹窗
  showDeleteConfirm?: boolean | ((value: any) => boolean | Promise<boolean>);
  //弹窗组件删除确认弹窗文案
  confirmText?: string;
  //隐藏整个组件的判断函数,只支持简单场景,如果需要用到的数据在controller中,需要在subscription中处理
  hiddenFunc?: (propertiesData: any) => boolean;
  //属性值传递给组件时进行的映射
  inputValueTransform?: (value: any) => any;
  //组件值传递给属性时进行的映射
  outputValueTransform?: (value: any) => any;
  //组件的参数props
  options?: any;
}

更多属性输入组件

河图属性设计器中内置了常用的属性输入组件,如下:

序号
组件名称
组件使用文档
组件说明
1
property-switch
开关选择器
2
property-text-input
单行文本输入组件
3
property-text-area
多行文本输入组件
4
property-checkbox
多选框组件
5
property-date-select
日期选择
6
property-modal
弹窗组件触发器
7
property-radio
单选框
8
property-select
下拉选择器
9
property-staff-selector
选人控件
10
property-select-dataitem
选择数据项
11
property-icon-select
图标选择控件
输入组件值的双向绑定
一般来说,单个属性对应的输入组件绑定的数据是节点对象下的同编码属性。通过配置valueMap,可以修改输入组件与节点对象之间双向数据绑定逻辑。


使用场景

流程现有流程节点有:传阅、用户活动、系统节点、连接点、子流程。客户想要在现有节点的基础上,简化节点的配置,隐藏部分属性配置,只配置客户需要的部分属性。需要注意的是,流程节点类型不会有增加,因此后端相关节点运行逻辑不需要调整。

扩展文件位置

packages\extension-template\src\workflow-design\extension-activities.ts

/**
 * 扩展节点数组
 */
export const extendActivities = [
  // {
  //   activityName: '扩展节点',
  //   name_i18n: {
  //     en: 'Example Extend Node',
  //   },
  //   width: 158,
  //   height: 40,
  //   icon: '&#xe910;',
  //   activityType: 'CONNECTION',
  //   extendActivityType: 'CustomNode',
  // },
];

扩展规范

[
  {
    activityName: '用户活动',
    name_i18n: {
      en: 'UserAction',
    },
    width: 158,
    height: 40,
    icon: '&#xe935;',
    activityType: 'PARTICIPANT',
  },
  {
    activityName: '系统活动',
    name_i18n: {
      en: 'BizAction',
    },
    width: 158,
    height: 40,
    icon: '&#xe947;',
    activityType: 'SYSTEM_ACTIVITY',
  },
  {
    activityName: '子流程',
    name_i18n: {
      en: 'SubInstance',
    },
    width: 158,
    height: 40,
    icon: '&#xe9d5;',
    activityType: 'SUB_INSTANCE',
  },
  {
    activityName: '连接点',
    name_i18n: {
      en: 'Connection',
    },
    width: 158,
    height: 40,
    icon: '&#xe914;',
    activityType: 'CONNECTION',
  },
  {
    activityName: '传阅',
    name_i18n: {
      en: 'Circularize',
    },
    width: 158,
    height: 40,
    icon: '&#xe910;',
    activityType: 'CIRCULATE',
  },
]

扩展的节点应该基于现有的节点配置,首先拷贝一份扩展自节点的配置(从用户活动扩展就复制用户活动的节点配置),然后修改节点的名称、图标、扩展节点类型

注意:activityType只能从现有的节点类型选取,不能设置新值。extendActivityType不能与现有的activityType重复。

示例

扩展节点配置

{
  activityName: '示例扩展节点',
    name_i18n: {
      en: 'Example Extend Node',
    },
  width: 158,
  height: 40,
  icon: '&#xe910;',
  activityType: 'CONNECTION',
  extendActivityType: 'CustomNode',
}


使用场景

  1. 修改现有的流程属性,节点属性,连接线属性(删除属性可以通过修改已有属性的可见性实现)

  2. 在现有的流程属性,节点属性,连接线属性上追加属性

  3. 扩展流程节点后,整体定义扩展的流程节点属性栏的配置

扩展文件位置

packages\extension-template\src\workflow-design\extension-attr-panel.ts

属性栏配置参考

扩展规范
所有属性栏扩展操作都是通过流程属性栏注册器attrPanelRegister中的方法调用完成的,attrPanelRegister已经引入到扩展文件中


使用场景

在扩展流程属性栏时需要使用到新的属性输入组件时

扩展文件位置

packages\extension-template\src\workflow-design\extension-attr-input-component.ts

import { propertyRegister } from 'cloudpivot-designer/property-panel';

import PropertyComponentDemo from './extension-components/property-component-demo.vue';
import ModalComponentDemo from './extension-components//modal-components/modal-component-demo.vue';

propertyRegister.append('property-component-demo', PropertyComponentDemo);
propertyRegister.append('modal-component-demo', ModalComponentDemo);
扩展规范
新组件文件位置规范
EXTEND-ATTR-INPUT-COMPONENT.TS
PROPERTY-COMPONENT-DEMO.V...
TSEXTEND-ATTR-PANELTS
EXTEND-COMPONENTS
MODAL-COMPONENTS
EXTEND-ACTIVITIES.TS
WORKFLOW-DESIGN
README.MD
ATTR-PANE
TYPINGS
TSEXTEN
TS
M
image.png

平铺组件放置在extend-components下,弹窗组件放置在modal-components下
组件实现规范
参考demo组件开发
示例


方法名称

说明

参数说明

append(panelCode: string, panelConfig: PanelConfig)

添加新的属性栏配置

属性栏code,属性栏配置

replace(panelCode: string, panelConfig: PanelConfig)

替换现有的属性栏配置

属性栏code,属性栏配置

replaceAttr(panelCode: string, attrConfig: PropertySchema)

替换现有属性栏中的某个属性

属性栏code,属性配置(包含属性的code)

appendAttr(panelCode: string, attrConfig: PropertySchema, groupKey?: string)

在现有属性栏中追加新属性,分组编码可选,如果不传入分组编码则在最后一个分组中添加

属性栏code, 属性配置,分组编码

appendGroup(panelCode: string, groupInfo: any)

在现有属性栏中添加分组

属性栏code,分组信息

getAttr(panelCode: string, attrCode: string)

获取现有的属性栏中,某个属性的具体配置

属性栏code, 属性code


图片名称
  • 1. 流程设计器元数据
  • 2.1 流程属性扩展-DEMO - 流程节点参与者支持密级
  • 2. 2 流程属性扩展-流程节点扩展开发说明文档
  • 2. 3 流程属性扩展-流程属性栏扩展开发说明文档
  • 2. 4 流程属性扩展-流程属性输入组件扩展开发说明文档
  • 2. 5 流程属性扩展-流程属性栏注册器可调用方法