前后端联动完整案例:任务集成插件
本文使用“任务集成插件”作为完整案例,串起 BPMAX 插件开发中最常见的一条业务链路:前端配置录入、后端逻辑执行、第三方接口调用。
学习目标
- 用一个真实案例理解插件的完整开发路径
- 学会从业务目标倒推前后端设计
- 学会组织流程配置、接口调用和错误处理
业务背景
插件解决什么问题
任务集成插件的核心目标,是让 BPMAX 流程环节与外部任务能力联动。典型场景是:
- 在某个流程环节启用外部任务创建
- 根据流程上下文生成任务内容
- 在适当时机更新或完成对应任务
为什么适合作为教学案例
这个插件的复杂度适中,具备一个完整业务插件常见的三个要素:
- 前端环节配置
- 后端第三方服务封装
- 明确的业务字段结构
它比“纯页面插件”更真实,但又没有复杂到必须先理解 Kafka 或大规模异步任务。
先看整体设计
前端负责什么
前端入口文件做的事情非常集中:
- 注册一个流程环节配置组件
- 定义配置字段名
- 提供默认值结构
代码核心如下:
import TaskStepConfig from './TaskStepConfig.vue';
BPMAX.flow.stepComponent({
field: 'plugin_task_integration',
component: TaskStepConfig,
defaultValue: {
enabled: false,
mapping_function: '',
platform_id: '',
},
});后端负责什么
后端服务层负责:
- 获取第三方访问令牌
- 创建外部任务
- 完成外部任务
也就是说,前端只采集配置,真正的三方调用全部放在后端。
插件配置数据如何流转
这一类插件建议遵循以下链路:
- 前端配置组件采集参数
- 配置写入流程或环节配置数据
- 后端在执行节点读取配置
- 服务层把配置转成第三方接口参数
- 调用第三方接口并处理结果
前端实现
注册流程环节配置组件
任务集成类插件使用 BPMAX.flow.stepComponent,这说明它的配置是“环节级”的,而不是整个流程统一配置一次。
原因是:
- 不是每个环节都要创建外部任务
- 每个环节的任务映射规则可能不同
配置项字段设计
当前默认字段包括:
enabledmapping_functionplatform_id
这类结构的优点是很清晰:
enabled:决定是否启用mapping_function:决定映射逻辑platform_id:决定使用哪个平台实例
一个最小的环节配置组件可以先写成:
<script setup lang="ts">
const model = defineModel<any>({
default: {
enabled: false,
mapping_function: '',
platform_id: '',
},
});
</script>
<template>
<div class="task-step-config">
<label>
<span>启用任务集成</span>
<input v-model="model.enabled" type="checkbox" />
</label>
<label>
<span>平台实例</span>
<input v-model="model.platform_id" type="text" placeholder="platform_a" />
</label>
<label>
<span>映射函数</span>
<input
v-model="model.mapping_function"
type="text"
placeholder="buildTaskPayload"
/>
</label>
</div>
</template>默认值与表单结构
这一类插件不要只用字符串存配置,建议一开始就把结构设计成对象,便于:
- 后续加字段
- 与历史版本兼容
- 做前端校验
后端实现
插件服务封装
任务集成类插件的服务层本质上是一个第三方能力封装层。它没有把 HTTP 逻辑散落在控制器中,而是统一放在服务层。
这样做的好处是:
- 控制器更轻
- 逻辑更易复用
- 便于单独调试第三方调用
控制器可以只保留参数接收和调用转发:
import BaseRest from '../rest.js';
@think.RestController()
export default class extends BaseRest {
async createTaskAction() {
const payload = this.post();
const result = await this.service('plugin_task_integration').createTask(payload);
return this.success(result);
}
}外部任务创建接口
服务层中有一个明确的方法:
async createExternalTask(platformConfig, payload) {
const accessToken = await this.getAccessToken(
platformConfig.app_id,
platformConfig.secret
);
const res = await this.httpClient.post('/tasks', payload, {
headers: {
Authorization: 'Bearer ' + accessToken,
'Content-Type': 'application/json; charset=utf-8',
},
});
return res;
}这里体现了一个值得复用的模式:
- 先解析平台配置
- 获取第三方 token
- 再调用业务接口
如果需要在创建前做字段映射,可以单独拆一个方法:
buildTaskPayload(project, config) {
return {
title: project.name,
description: `来自流程 ${project.flow_name} 的任务`,
owner: config.owner_id,
source_id: project.guid,
};
}外部任务完成接口
插件还提供了任务完成能力:
async completeExternalTask(platformConfig, taskId) {
const accessToken = await this.getAccessToken(
platformConfig.app_id,
platformConfig.secret
);
const res = await this.httpClient.patch(
'/tasks/' + taskId,
{
status: 'completed',
completed_at: Date.now(),
},
{
headers: {
Authorization: 'Bearer ' + accessToken,
'Content-Type': 'application/json; charset=utf-8',
},
}
);
return res;
}这说明插件不仅能“创建任务”,还应该考虑后续状态同步。对集成类插件来说,这一点很重要。
配置与运行
平台参数准备
运行这类插件前,通常至少要准备:
- 第三方平台
app_id - 第三方平台
secret - 业务侧对应的平台实例配置
调试顺序建议
建议按这个顺序调试:
- 先确认前端配置组件是否显示
- 再确认配置数据是否正确保存
- 再确认后端是否能拿到平台配置
- 最后确认第三方接口调用是否成功
成功与失败的判断方式
不要只看页面有没有报错。至少要同时确认:
- 前端配置是否已生效
- 后端是否真正发出请求
- 第三方是否返回成功
- 返回结果是否被后续流程正确使用
从这个案例中抽象出的设计方法
前端只负责采集与展示
前端组件尽量只负责:
- 显示配置项
- 收集用户输入
- 维护默认结构
后端负责调用与容错
所有三方调用、鉴权、错误处理都应尽量在后端完成,避免:
- 泄露密钥
- 把集成逻辑分散在页面里
第三方适配应封装在独立服务中
不要把第三方接口调用直接散落在控制器中。每种外部能力都应该有稳定的服务封装层。
可进一步扩展的方向
增加状态回写
例如 BPMAX 状态变化后自动回写外部任务状态。
增加重试与幂等
第三方任务创建失败时,可以考虑:
- 重试策略
- 幂等标识
- 人工补偿
增加日志与监控
集成类插件如果没有日志,出问题时几乎无法定位。至少建议记录:
- 平台实例
- 请求接口
- 核心参数摘要
- 返回结果
