Camunda JavaScript SDK:浏览器端流程交互

Camunda JavaScript SDK:浏览器端流程交互

【免费下载链接】camunda-bpm-platform camunda/camunda-bpm-platform: 一个基于 Java 的业务流程管理(BPM)平台,用于管理和执行企业业务流程。适合用于管理和执行各种业务流程,如审批流程、工作流和供应链管理等。 【免费下载链接】camunda-bpm-platform 项目地址: https://gitcode.com/GitHub_Trending/ca/camunda-bpm-platform

还在为前后端分离架构下的流程交互而烦恼?Camunda JavaScript SDK 为您提供了在浏览器端直接与 Camunda 流程引擎交互的能力,让前端开发者也能轻松处理业务流程任务。本文将深入解析 Camunda JavaScript SDK 的核心功能和使用方法,帮助您构建现代化的流程驱动应用。

读完本文您将获得

  • ✅ Camunda JavaScript SDK 的完整架构解析
  • ✅ 核心 API 的详细使用指南和代码示例
  • ✅ 表单处理、任务管理的最佳实践
  • ✅ 错误处理和本地存储的实用技巧
  • ✅ 与后端流程引擎的无缝集成方案

Camunda JavaScript SDK 架构概览

Camunda JavaScript SDK 是一个专门为浏览器环境设计的客户端库,提供了与 Camunda 流程引擎 REST API 交互的完整解决方案。其核心架构采用模块化设计,主要包含以下几个关键组件:

mermaid

核心 API 功能详解

1. 客户端初始化与配置

Camunda JavaScript SDK 的核心入口是 CamundaClient 类,它负责管理与流程引擎的连接和所有资源操作。

// 初始化 Camunda 客户端
const client = new CamSDK.Client({
  apiUri: 'http://localhost:8080/engine-rest',
  engine: 'default', // 可选,默认为 'default'
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your-token-here'
  }
});

// 获取任务资源实例
const taskResource = client.resource('task');

2. 任务管理 API

任务管理是 SDK 的核心功能,支持任务的查询、领取、完成等完整生命周期操作。

查询任务列表
// 查询分配给当前用户的任务
taskResource.list({
  assignee: 'current-user',
  active: true,
  sortBy: 'created',
  sortOrder: 'desc',
  firstResult: 0,
  maxResults: 50
}, function(err, result) {
  if (err) {
    console.error('获取任务列表失败:', err);
    return;
  }
  
  const tasks = result._embedded.task;
  tasks.forEach(task => {
    console.log(`任务ID: ${task.id}, 名称: ${task.name}, 创建时间: ${task.created}`);
  });
});
完成任务
// 完成任务并更新流程变量
taskResource.complete({
  id: 'task-123',
  variables: {
    approvalResult: {
      value: 'approved',
      type: 'String'
    },
    comment: {
      value: '申请已审核通过',
      type: 'String'
    }
  }
}, function(err, result) {
  if (err) {
    console.error('完成任务失败:', err);
    return;
  }
  console.log('任务完成成功');
});
任务领取与释放
// 领取任务
taskResource.claim('task-123', 'user-456', function(err) {
  if (err) {
    console.error('领取任务失败:', err);
    return;
  }
  console.log('任务领取成功');
});

// 释放任务
taskResource.unclaim('task-123', function(err) {
  if (err) {
    console.error('释放任务失败:', err);
    return;
  }
  console.log('任务释放成功');
});

3. 表单处理功能

CamundaForm 类是专门为处理嵌入式表单设计的,提供了强大的表单渲染、数据绑定和提交功能。

表单初始化与渲染
// 初始化表单
const camForm = new CamSDK.Form({
  client: client,
  taskId: 'task-123',
  containerElement: document.getElementById('form-container'),
  formUrl: '/forms/approval-form.html'
});

// 监听表单事件
camForm.on('form-loaded', function() {
  console.log('表单加载完成');
});

camForm.on('variables-applied', function() {
  console.log('流程变量已应用到表单');
});

camForm.on('submit-success', function() {
  console.log('表单提交成功');
  alert('操作成功!');
});
表单提交与错误处理
// 提交表单
document.getElementById('submit-btn').addEventListener('click', function() {
  camForm.submit(function(err, result) {
    if (err) {
      console.error('表单提交失败:', err);
      alert('提交失败: ' + err.message);
      return;
    }
    console.log('表单提交成功:', result);
  });
});

// 报告BPMN错误
document.getElementById('error-btn').addEventListener('click', function() {
  camForm.error('APPROVAL_REJECTED', '申请不符合政策要求', function(err) {
    if (err) {
      console.error('报告错误失败:', err);
      return;
    }
    console.log('BPMN错误报告成功');
  });
});

// 报告BPMN升级
document.getElementById('escalate-btn').addEventListener('click', function() {
  camForm.escalate('MANAGER_APPROVAL_NEEDED', function(err) {
    if (err) {
      console.error('报告升级失败:', err);
      return;
    }
    console.log('BPMN升级报告成功');
  });
});

高级功能与最佳实践

1. 本地存储与数据持久化

CamundaForm 提供了自动的本地存储功能,确保用户在填写表单过程中不会因页面刷新而丢失数据。

// 手动保存表单状态
camForm.store(function(err) {
  if (err) {
    console.error('保存表单状态失败:', err);
    return;
  }
  console.log('表单状态已保存到本地存储');
});

// 检查是否有可恢复的数据
if (camForm.isRestorable()) {
  if (confirm('检测到未提交的表单数据,是否恢复?')) {
    camForm.restore(function(err) {
      if (err) {
        console.error('恢复表单数据失败:', err);
        return;
      }
      console.log('表单数据恢复成功');
    });
  }
}

// 清理过期的本地存储数据
CamSDK.Form.cleanLocalStorage(Date.now() - 24 * 60 * 60 * 1000); // 清理24小时前的数据

2. 文件上传处理

SDK 内置了文件上传功能,支持对上传文件的大小验证和自动转换。

<!-- HTML 表单中的文件上传字段 -->
<input type="file" 
       cam-variable-name="attachment" 
       cam-variable-type="File"
       cam-max-filesize="10485760" 
       accept=".pdf,.doc,.docx">
// 文件上传的自动处理
camForm.on('variables-applied', function() {
  const fileVariable = camForm.variableManager.variables['attachment'];
  if (fileVariable && fileVariable.contentUrl) {
    // 显示已上传的文件链接
    const downloadLink = `<a href="${fileVariable.contentUrl}" target="_blank">下载附件</a>`;
    document.getElementById('file-preview').innerHTML = downloadLink;
  }
});

3. 自定义表单字段处理器

您可以扩展 SDK 的表单处理能力,添加自定义的字段类型处理器。

// 自定义颜色选择器字段处理器
const ColorPickerHandler = function(element, variableManager, form) {
  this.element = $(element);
  this.variableManager = variableManager;
  this.form = form;
  this.variableName = this.element.attr('cam-variable-name');
  
  this.initialize();
};

ColorPickerHandler.prototype.initialize = function() {
  const self = this;
  
  // 初始化颜色选择器
  this.element.colorPicker({
    onChange: function(color) {
      self.variableManager.setVariableValue(self.variableName, color);
    }
  });
};

ColorPickerHandler.prototype.applyValue = function() {
  const value = this.variableManager.getVariableValue(this.variableName);
  if (value) {
    this.element.colorPicker('setColor', value);
  }
};

ColorPickerHandler.prototype.getValue = function() {
  const color = this.element.colorPicker('getColor');
  this.variableManager.setVariableValue(this.variableName, color);
};

// 注册自定义处理器
const form = new CamSDK.Form({
  client: client,
  taskId: 'task-123',
  formElement: document.getElementById('my-form'),
  formFieldHandlers: [
    CamSDK.form.fields.InputFieldHandler,
    CamSDK.form.fields.ChoicesFieldHandler,
    ColorPickerHandler, // 添加自定义处理器
    CamSDK.form.fields.FileDownloadHandler
  ]
});

实战案例:审批流程集成

下面是一个完整的审批流程集成示例,展示了如何在实际项目中使用 Camunda JavaScript SDK。

class ApprovalWorkflow {
  constructor(apiUrl, engineName) {
    this.client = new CamSDK.Client({
      apiUri: apiUrl,
      engine: engineName || 'default'
    });
    this.taskResource = this.client.resource('task');
  }
  
  // 获取用户待办任务
  async getUserTasks(userId, filters = {}) {
    return new Promise((resolve, reject) => {
      const params = {
        assignee: userId,
        active: true,
        ...filters
      };
      
      this.taskResource.list(params, (err, result) => {
        if (err) return reject(err);
        resolve(result._embedded.task || []);
      });
    });
  }
  
  // 初始化任务表单
  initTaskForm(taskId, containerId) {
    return new CamSDK.Form({
      client: this.client,
      taskId: taskId,
      containerElement: document.getElementById(containerId)
    });
  }
  
  // 提交审批结果
  async submitApproval(taskId, decision, comment) {
    return new Promise((resolve, reject) => {
      this.taskResource.complete({
        id: taskId,
        variables: {
          approvalDecision: {
            value: decision,
            type: 'String'
          },
          approvalComment: {
            value: comment,
            type: 'String'
          }
        }
      }, (err, result) => {
        if (err) return reject(err);
        resolve(result);
      });
    });
  }
  
  // 监听任务事件
  setupTaskEventListeners(form) {
    form.on('form-loaded', () => this.onFormLoaded());
    form.on('variables-fetched', () => this.onVariablesFetched());
    form.on('submit-success', (result) => this.onSubmitSuccess(result));
    form.on('submit-failed', (error) => this.onSubmitFailed(error));
  }
  
  onFormLoaded() {
    console.log('审批表单加载完成');
    this.showLoading(false);
  }
  
  onVariablesFetched() {
    console.log('流程变量获取完成');
    this.updateUIWithVariables();
  }
  
  onSubmitSuccess(result) {
    console.log('审批提交成功', result);
    alert('审批操作已完成!');
    this.redirectToTaskList();
  }
  
  onSubmitFailed(error) {
    console.error('审批提交失败', error);
    alert('提交失败: ' + error.message);
  }
  
  // UI 相关方法
  showLoading(show) {
    document.getElementById('loading').style.display = show ? 'block' : 'none';
  }
  
  updateUIWithVariables() {
    // 根据流程变量更新UI显示
  }
  
  redirectToTaskList() {
    window.location.href = '/tasks';
  }
}

// 使用示例
const workflow = new ApprovalWorkflow('http://localhost:8080/engine-rest');

// 页面加载时初始化
document.addEventListener('DOMContentLoaded', async () => {
  try {
    const tasks = await workflow.getUserTasks('current-user-id');
    if (tasks.length > 0) {
      const form = workflow.initTaskForm(tasks[0].id, 'form-container');
      workflow.setupTaskEventListeners(form);
    }
  } catch (error) {
    console.error('初始化失败:', error);
  }
});

性能优化与错误处理

1. 请求优化策略

// 配置HTTP客户端优化
const client = new CamSDK.Client({
  apiUri: 'http://localhost:8080/engine-rest',
  resources: {
    task: {
      timeout: 30000, // 30秒超时
      retry: {
        attempts: 3,
        delay: 1000
      }
    }
  }
});

// 批量操作减少请求次数
async function batchCompleteTasks(taskIds, variables) {
  const promises = taskIds.map(taskId => {
    return new Promise((resolve, reject) => {
      client.resource('task').complete({
        id: taskId,
        variables: variables
      }, (err, result) => {
        if (err) reject(err);
        else resolve(result);
      });
    });
  });
  
  return Promise.all(promises);
}

2. 错误处理与重试机制

class ResilientCamundaClient {
  constructor(baseConfig) {
    this.client = new CamSDK.Client(baseConfig);
    this.retryConfig = {
      maxAttempts: 3,
      retryDelay: 1000,
      retryableErrors: ['ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT']
    };
  }
  
  async withRetry(operation, ...args) {
    let lastError;
    
    for (let attempt = 1; attempt <= this.retryConfig.maxAttempts; attempt++) {
      try {
        return await new Promise((resolve, reject) => {
          operation(...args, (err, result) => {
            if (err) reject(err);
            else resolve(result);
          });
        });
      } catch (error) {
        lastError = error;
        
        if (attempt === this.retryConfig.maxAttempts) {
          break;
        }
        
        if (!this.isRetryableError(error)) {
          break;
        }
        
        console.warn(`操作失败,第${attempt}次重试...`, error);
        await this.delay(this.retryConfig.retryDelay * attempt);
      }
    }
    
    throw lastError;
  }
  
  isRetryableError(error) {
    return this.retryConfig.retryableErrors.some(code => 
      error.code === code || error.message.includes(code)
    );
  }
  
  delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
  
  // 包装常用方法
  async listTasks(params) {
    return this.withRetry(
      this.client.resource('task').list.bind(this.client.resource('task')),
      params
    );
  }
  
  async completeTask(taskId, variables) {
    return this.withRetry(
      this.client.resource('task').complete.bind(this.client.resource('task')),
      { id: taskId, variables }
    );
  }
}

总结与展望

Camunda JavaScript SDK 为前端开发者提供了强大的流程交互能力,使得在浏览器环境中处理复杂的业务流程成为可能。通过本文的详细解析,您应该已经掌握了:

  1. 核心架构理解:深入了解 SDK 的模块化设计和组件关系
  2. API 熟练使用:掌握任务管理、表单处理等核心功能的调用方式
  3. 高级功能应用:学会使用本地存储、文件处理、自定义扩展等高级特性
  4. 实战开发技能:通过完整案例了解在实际项目中的集成方法
  5. 性能优化策略:掌握错误处理和性能优化的最佳实践

随着前端技术的不断发展,Camunda JavaScript SDK 将继续演进,为构建更加现代化、响应式的流程驱动应用提供强大支持。建议在实际项目中逐步应用这些技术,根据具体需求进行定制和优化,从而充分发挥 Camunda 流程引擎的强大能力。

【免费下载链接】camunda-bpm-platform camunda/camunda-bpm-platform: 一个基于 Java 的业务流程管理(BPM)平台,用于管理和执行企业业务流程。适合用于管理和执行各种业务流程,如审批流程、工作流和供应链管理等。 【免费下载链接】camunda-bpm-platform 项目地址: https://gitcode.com/GitHub_Trending/ca/camunda-bpm-platform

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值