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

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

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

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

    • 系统公告
    • 项目日历
    • 超时自动化
    • 报告自动生成
    • 流程资源档案
  • 文档更新记录
  • 系统更新说明
  • 插件开发入门

    • 插件开发
    • 插件架构与加载机制
    • 环境准备与开发模式
    • 第一个最小插件
  • 插件能力开发

    • 前端扩展点实战
    • 后端扩展点实战
    • 前后端联动完整案例:任务集成插件
  • 插件运行机制

    • 配置、安装、升级与发布
    • 定时任务与异步处理
    • Hook 机制与平台事件接入
    • 外部系统集成模式
  • 进阶与参考

    • 调试与排错
    • 设计规范与最佳实践
    • 能力类型索引与选型

外部系统集成模式

本文总结 BPMAX 插件最常见的外部系统集成模式,帮助开发者按问题类型选择合适的插件设计方案。

学习目标

  • 理解常见企业插件集成模式
  • 学会为不同类型的外部系统设计插件结构
  • 理解鉴权、回调、缓存、重试和队列的组合方式

模式一:自定义鉴权插件

适用场景

适合平台已有统一调用链,但第三方要求特殊鉴权方式的场景。

注册时机

通常在插件启动时完成注册,使后续调用链能直接复用。

Token 获取与缓存

鉴权插件应优先考虑:

  • token 获取逻辑封装
  • 缓存过期时间
  • 提前刷新策略

一个最小服务示例如下:

export default class PluginAuthService extends think.Service {
  async getAccessToken(config) {
    const cacheKey = `plugin_auth:${config.app_id}`;
    const cached = await this.redis.get(cacheKey);

    if (cached) {
      return cached;
    }

    const res = await this.http.post('/oauth/token', {
      app_id: config.app_id,
      secret: config.secret,
    });

    const token = res.data.access_token;
    await this.redis.set(cacheKey, token, 'EX', 7000);
    return token;
  }
}

失败处理

鉴权失败通常不是“多试几次就好”。需要区分:

  • 临时网络失败
  • 配置错误
  • 凭证失效

调用侧可以这样区分错误:

try {
  const token = await this.service('plugin_auth').getAccessToken(config);
  return token;
} catch (error) {
  think.logger.error('[plugin_auth] get token failed', error);
  throw error;
}

模式二:任务/消息协同插件

适用场景

适合把流程事件同步成外部任务、消息或通知对象。

流程配置与任务映射

这类插件通常需要:

  • 在流程或环节中收集配置
  • 把平台数据映射成第三方字段
  • 设计任务创建与更新规则

任务映射函数可以单独维护:

function buildTaskPayload(project, config) {
  return {
    title: project.name,
    description: project.remark || '',
    owner_id: config.owner_id,
    source_id: project.guid,
  };
}

状态回写设计

如果第三方对象有生命周期,建议同时考虑:

  • 创建
  • 更新
  • 完成
  • 失败补偿

状态回写服务可以先定义成:

async syncTaskStatus(taskId, status, config) {
  const token = await this.service('plugin_auth').getAccessToken(config);

  return this.http.patch(
    `/tasks/${taskId}`,
    { status },
    {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    }
  );
}

模式三:组织架构同步插件

适用场景

适合平台组织、团队、用户等对象要与第三方系统保持同步的场景。

事件驱动与全量刷新结合

只靠事件驱动通常不够,建议同时保留:

  • 增量同步
  • 手工全量刷新
  • 异常补偿

例如可以保留两个入口:

async syncDepartmentEvent(payload) {
  return this.service('plugin_org_sync').syncSingle(payload);
}

async syncAllDepartments() {
  return this.service('plugin_org_sync').syncAll();
}

模型映射与唯一标识设计

这类插件最重要的是唯一标识设计。必须先明确:

  • 平台和第三方的对应主键是什么
  • 用户和团队的绑定规则是什么

模式四:资源与指标上报插件

适用场景

适合把调用量、资源消耗、对象数量等数据定期上报到外部平台。

队列缓存

为了降低上报链路耦合,建议先本地收集,再异步上报。

例如:

await this.redis.lpush(
  'plugin_metrics:queue',
  JSON.stringify({
    metric: 'task_count',
    value: 12,
    created_at: Date.now(),
  })
);

批量上报

批量策略需要平衡:

  • 实时性
  • 请求次数
  • 失败影响范围

批量发送可以先写成:

async reportMetricsBatch() {
  const items = await this.redis.lrange('plugin_metrics:queue', 0, 99);
  if (!items.length) return;

  const payload = items.map(item => JSON.parse(item));
  await this.http.post('/metrics/batch', payload);
}

重试与监控

这类插件通常必须具备:

  • 失败重试
  • 状态统计
  • 队列清理

通用设计要点

配置隔离

每个外部系统集成都应有独立配置,避免多个能力共用一份难以维护的大配置。

凭证管理

不要把凭证散落在页面逻辑里,尽量统一交给后端服务层处理。

幂等与重试

只要涉及网络调用和异步任务,就要同时考虑幂等和重试,不能只做其一。

日志与可观测性

至少应能回答:

  • 调用了哪个外部接口
  • 用了哪组配置
  • 成功还是失败
  • 失败原因是什么

下一步

  • 调试与排错
  • 能力类型索引与选型
Prev
Hook 机制与平台事件接入