BPMAXBPMAX
  • 快速入门
  • 核心概念
  • 管理员手册
  • 仿真和回放
  • 流程相关脚本
  • 表单相关脚本
  • 数据集相关脚本
  • 界面相关脚本
  • 系统相关脚本
  • 流程集成
  • 数据集
  • OpenAPI
  • 实体列表
  • 插件开发
  • 日志排查
  • 飞书平台

    • 同步组织架构
    • 同步团队组织架构
    • 一键拉群
    • 高级卡片消息
    • 服务台能力
  • 实用功能

    • 系统公告
    • 项目日历
    • 超时自动化
    • 报告自动生成
  • 文档更新记录
  • 系统更新说明
  • 快速入门
  • 核心概念
  • 管理员手册
  • 仿真和回放
  • 流程相关脚本
  • 表单相关脚本
  • 数据集相关脚本
  • 界面相关脚本
  • 系统相关脚本
  • 流程集成
  • 数据集
  • OpenAPI
  • 实体列表
  • 插件开发
  • 日志排查
  • 飞书平台

    • 同步组织架构
    • 同步团队组织架构
    • 一键拉群
    • 高级卡片消息
    • 服务台能力
  • 实用功能

    • 系统公告
    • 项目日历
    • 超时自动化
    • 报告自动生成
  • 文档更新记录
  • 系统更新说明
  • 流程相关脚本

    • 使用场景概览
    • 项目上下文数据

使用场景概览

流程Meta节点

项目名称模板

  • 运行环境:后端,创建项目时
  • 一些流程中的项目不需要填写项目名称,则需要配置项目名称模板,以便自动生成项目名称。

任务标题模板

  • 运行环境:前端,渲染任务列表时
  • 默认任务会使用项目名称作为任务标题,有的时候在我的任务列表中不太好区分,需要在标题中增加更多的信息,可以配置任务标题模板,以便自动生成任务标题。

计算属性

  • 运行环境:后端,相关项目或环节发生变化时
  • 项目的某些属性是由其他属性计算得到的,例如项目的总金额是由项目的单价和数量计算得到的,这种属性称为计算属性,可以配置计算属性,以便自动计算。

分配后续环节负责人

  • 运行环境:前端,渲染人员分配组件时
  • 用于控制是否显示当前分配组件,以及动态加载默认分配人员。

环节可见性配置

  • 运行环境:前端,渲染流程日志列表时
  • 用户控制流程日志列表中的环节是否可见。

自定义跳转逻辑

  • 运行环境:后端,项目创建后执行
  • 控制项目创建后动态跳转的第一个节点,一般会依赖创建项目时的表单数据。

插件相关的配置

  • 见各插件的文档

环节节点

分配后续环节负责人

  • 运行环境:前端,渲染人员分配组件时
  • 用于控制是否显示当前分配组件,以及动态加载默认分配人员。

分配当前环节负责人

脚本

将当前环节负责人分配脚本与指定表单绑定(ctx)
类型
interface OwnerItem {
  /** 负责人用户id */
  owner_id: number,
  /** 处理状态 0 未处理, 1 通过, 2 拒绝  */
  status?: number,
  [p: string]: any;
}
interface FlowStepId2Owners {
  /** 为0时为设置项目负责人 */
  [flow_step_id: string]: OwnerItem[];
};

interface ResetProjectStepOwnerOption {
  /** 是否全匹配, 
   * 矩阵和脚本分配环节负责人时默认为true: 删除掉老负责人数据中在新配置中不存在的人
   * 为false时只会向环节中添加参数中不存在的负责人, 不会去除系统中多余的负责人
   */
  full_match?: boolean;
  /** 
   * 变更原因
   */
  reason?: string;
  /** 
   * 操作批次,修改多个项目多个环节负责人可以共享一个批次
   * 用于交接动作一次性重新分配多个项目多个环节负责人,记录同一次操作造成的多次影响
   */
  batch_id?: string;
  /** 操作人id */
  user_id?: number;
  /** 
   * 触发有效环节负责人变更后是否发送变更消息给相关用户(新旧负责人)
   * 矩阵和脚本分配环节负责人时默认为true
   */
  send_message?: boolean;
  /** 需要删除的负责人
   * full_match为false时仍要删除的负责人,用于环节转办以及交接时在不影响其余环节负责人的情况下移除要转办的负责人
   * 即当当前环节负责人为 A B C 时  要将A转办给D, 需要在保留B C 的情况下删除 A
   */
  flow_step_id_to_owners_del?: FlowStepId2Owners;
  /** 
   * 更新环节负责人时是否触发es刷新
   * 矩阵和脚本分配环节负责人时默认为true
   */
  trigger_es_refresh?: boolean;
  /** 
   * 工作区, 决定变更负责人时要将变更消息发送到哪个工作区
   * 矩阵和脚本分配环节负责人时默认发送到项目所在的工作区
   */
  workspace?: string;
}
interface Context {
  $subScribeForm(form_id: number, option: Partial<ResetProjectStepOwnerOption>): Promise<void>;
  $subscribe(table: string, id: any, option: Partial<ResetProjectStepOwnerOption>): Promise<void>;
}
示例
// 当form_id = 1的表单中控件被修改时将会重新执行当前脚本附加新的环节负责人
const form_id = 1;
await ctx.$subScribeForm(form_id, {
  reason: '测试原因'
});
// 返回当前负责人列表
return [ 1 ];

矩阵

将当前环节负责人分配矩阵与指定矩阵绑定(ctx)
  • 无法订阅一个不存在于系统中的记录,对于运行完次脚本之后新增加的可以匹配到的记录不会订阅(订阅所有省份符合河北的总监作为环节负责人,则后续新增一条河北省份记录不会导致重新触发负责人分配)
类型
type MatrixSelectOptions = {
  /** 流程标识 `${flow_type}:${flow_key}` */
  flow?: string;
  /** 是否保持同步,为true时 对应搜索记录发生变更时触发环节负责人同步 */
  auto_subscribe?: boolean;
  /** 订阅选项 */
  subscribe_option?: Partial<ResetProjectStepOwnerOption>;
}
interface Context {
  $matrixService {
    /**
     * 原生es搜索矩阵
     * @param query any es查询语句body.query
     * @param flow 流程标识 `${flow_type}:${flow_key}`
     * @returns 
     */
    select(query: any, option?: MatrixSelectOptions): Promise<any>;
    /**
     * matrix简易请求
     */
    selectByObject(queryObject: Record<string, any>, option?: MatrixSelectOptions): Promise<any>;
    /**
     * 订阅矩阵
     * @param pid 矩阵所绑定的项目id
     * @param option 订阅选项
     */
    subscribeMatrix(pid: number, option?: Partial<ResetProjectStepOwnerOption>): Promise<void>;
  }
}
示例

// 方案1, 传入自动订阅参数
const result = await ctx.$matrixService.selectByObject({
  province: "河北",
}, {
  // 自动订阅命中的矩阵记录,对应矩阵表单修改时重新分配环节负责人
  auto_subscribe: true,
  // 订阅配置, 详见
  subscribe_option: {
    full_match: true,
  }
});

// 方案2, 手动调用订阅api
result.forEach(i => {
  ctx.$matrixService.subscribeMatrix(i.__id);
});

// 河北省的du_dao作为环节负责人
return result.map((i) => i.du_dao);

条件节点的定义

  • 运行环境:后端,环节流转时执行
  • 用于控制环节依据项目的某些属性值来决定流转到多个后续环节中的哪一个。

可用参数

参数名类型描述
stepobject当前环节
stepsobject所有项目中已存在的环节,使用环节模板ID来获取
projectobject项目数据
optionsArray目标跳转环节的集合

返回值

目标跳转环节的下标

示例代码

const lastStep = steps['1681717443449'];
const targetSteps = options;

return Math.max(targetSteps.indexOf(lastStep.from_flow_step_id), 0);

说明:如果lastStep所代表的环节的来源环节与备选环节某环节一致,则返回该环节的下标,否则返回0。

自动创建流程

配置页面

  • 点击项目创建规则和数据映射时可以输入代码
  • 运行环境:后端,环节流转时执行
  • 用于在流程环节中自动创建子流程,支持动态生成子流程数据,并可与父流程表单建立订阅关系
  • 支持子项目基本信息的同步,如项目名称、状态、扩展配置等字段的自动更新

函数定义

// 返回要创建的子项目列表
const autoCreateSubProject = (ctx: AutoCreateSubProjectContext) : Promise<CreateProjectTaskDto[]>
// 返回要创建的子项目列表
interface AutoCreateSubProjectContext extends ServerProjectContext {
  // 此标识用于识别是否由订阅触发, 脚本中可以借用此标识规避一些副作用(比如运行创建子流程脚本时需要额外创建一些数据)
  trigger_by_subscription: boolean;
}

type CreateProjectTaskDto = {
  flow_type: string;
  key: string;
  /**
   * 若为true, 会先把对应的用户创建的项目删除再走创建操作
   * @see packages/huanpingtong-server/src/model/project.ts#createProjectByTask
   */
  delete: boolean;
  data: CreateProjectTaskDataDto;
}
type CreateProjectTaskDataDto = {
  form: SimpleFormValue;
  contract_id?:string;
  subscribe?: {
    // 是否跟随新的task结果自动删除
    auto_delete?: boolean
    // 是否跟随新的task结果自动创建新的子流程项目
    auto_add?: boolean;
    subscriptions: SubscriptionItem[]
  };
} & ProjectCreateDto;

export interface BasicSubscriptionItem {
  // 处理类型和设置
  handle: string;
  setting?: Record<string, any>;
  // 被订阅者表名
  publisher_table: string;
  // 被订阅者表单id
  publisher_id: number;
  // 是否激活
  enable: boolean;
}
// 处理类型声明
export interface FormSubscriptionItem extends BasicSubscriptionItem {
  handle: 'form';
  setting?: Record<string, any>;
}
export interface ProjectSubscriptionItem extends BasicSubscriptionItem {
  handle: 'project';
  setting?: {
    // 要同步的子项目基础字段
    // 特别的,当存在ext_config 字段时, 会和当前数据库中的project.ext_config 进行Object.assign 合并操作
    fields?: (keyof ProjectCreateDto)[];
  };
}

export type SubscriptionItem = FormSubscriptionItem | ProjectSubscriptionItem;

示例代码

示例1:创建固定流程类型的多个子项目
// 根据主项目的表单数据创建多个子流程
const itemList = ctx.$META_FORM_KEY.sub_form_list || [];

// 为每个列表项创建一个子流程
return itemList.map((item, index) => {
  return {
    // 使用唯一ID作为contract_id,用于订阅时后续更新或删除
    contract_id: `item_${item.id}`,
    
    // 子项目名称
    name: `${ctx.project.name}-子项目${index + 1}`,
    // 子项目表单数据
    form: {
      key_to_value: {
        name: item.name,
        price: item.price,
      }
    },
    
    // 订阅父项目的表单变化
    subscribe: {
      auto_delete: true,  // 当父项目中对应项被删除时,自动删除子项目
      auto_add: true,     // 当父项目中新增项时,自动创建新的子项目
      subscriptions: [
        {
          handle: 'form',
          publisher_table: 'form',
          publisher_id: mainFormId,
          enable: true
        },
        {
          handle: 'project',
          publisher_table: 'project',
          publisher_id: ctx.project.id,
          enable: true,
          setting: {
            fields: ['name', 'status', 'ext_config'] // 同步项目基本信息
          }
        }
      ]
    }
  };
});
示例2:使用项目基本信息订阅
// 创建子项目并订阅父项目的基本信息变更
return [
  {
    contract_id: "main_sub_project",
    flow_type: "flow_type_B",
    key: "key_B",
    delete: false,
    data: {
      name: `${ctx.project.name}-辅助项目`,
      form: {
        key_to_value: {
          reference_id: ctx.project.id
        }
      },
      subscribe: {
        auto_delete: true,
        subscriptions: [
          // 订阅父项目的基本信息变更
          {
            handle: 'project',
            publisher_table: 'project',
            publisher_id: ctx.project.id,
            enable: true,
            setting: {
              // 指定需要同步的字段
              fields: ['name', 'status', 'ext_config']
            }
          }
        ]
      }
    }
  }
];

动态修改环节配置

  • 运行环境:前端,渲染环节处理页时
  • 用于在进入环节处理面的时候动态控制环节的配置,例如动态可用的操作

插件相关的配置

  • 见各插件的文档
Next
项目上下文数据