logologo
Bắt đầu
Hướng dẫn
Phát triển
Plugin
API
English
简体中文
日本語
한국어
Deutsch
Français
Español
Português
Русский
Italiano
Türkçe
Українська
Tiếng Việt
Bahasa Indonesia
ไทย
Polski
Nederlands
Čeština
العربية
עברית
हिन्दी
Svenska
Bắt đầu
Hướng dẫn
Phát triển
Plugin
API
logologo

Giới thiệu

FlowEngine là gì?
Mối quan hệ giữa FlowEngine và plugin
Bắt đầu nhanh
Lộ trình học tập

Hướng dẫn

Đăng ký FlowModel
Tạo FlowModel
Render FlowModel
Luồng sự kiện và cấu hình FlowModel
Lưu trữ bền vững FlowModel
Vòng đời FlowModel
Hệ thống ngữ cảnh của FlowModel
Cơ chế phản ứng: Observable
FlowModel vs React.Component

Definitions

ModelDefinition
FlowDefinition
EventDefinition
ActionDefinition
StepDefinition
Previous PageEventDefinition
Next PageStepDefinition
TIP

Tài liệu này được dịch bởi AI. Đối với bất kỳ thông tin không chính xác nào, vui lòng tham khảo phiên bản tiếng Anh

#ActionDefinition

ActionDefinition định nghĩa các hành động có thể tái sử dụng, những hành động này có thể được tham chiếu trong nhiều luồng công việc và bước khác nhau. Một hành động là đơn vị thực thi cốt lõi trong FlowEngine, đóng gói logic nghiệp vụ cụ thể.

#Định nghĩa kiểu

interface ActionDefinition<TModel extends FlowModel = FlowModel, TCtx extends FlowContext = FlowContext> {
  name: string;
  title?: string;
  handler: (ctx: TCtx, params: any) => Promise<any> | any;
  uiSchema?: Record<string, ISchema> | ((ctx: TCtx) => Record<string, ISchema> | Promise<Record<string, ISchema>>);
  defaultParams?: Record<string, any> | ((ctx: TCtx) => Record<string, any> | Promise<Record<string, any>>);
  beforeParamsSave?: (ctx: FlowSettingsContext<TModel>, params: any, previousParams: any) => void | Promise<void>;
  afterParamsSave?: (ctx: FlowSettingsContext<TModel>, params: any, previousParams: any) => void | Promise<void>;
  useRawParams?: boolean | ((ctx: TCtx) => boolean | Promise<boolean>);
  uiMode?: StepUIMode | ((ctx: FlowRuntimeContext<TModel>) => StepUIMode | Promise<StepUIMode>);
  scene?: ActionScene | ActionScene[];
  sort?: number;
}

#Cách thức đăng ký

// Đăng ký toàn cục (qua FlowEngine)
const engine = new FlowEngine();
engine.registerAction({
  name: 'loadDataAction',
  title: 'Load Data',
  handler: async (ctx, params) => {
    // Logic xử lý
  }
});

// Đăng ký cấp mô hình (qua FlowModel)
class MyModel extends FlowModel {}
MyModel.registerAction({
  name: 'processDataAction',
  title: 'Process Data',
  handler: async (ctx, params) => {
    // Logic xử lý
  }
});

// Sử dụng trong một luồng công việc
MyModel.registerFlow({
  key: 'dataFlow',
  steps: {
    step1: {
      use: 'loadDataAction',  // Tham chiếu hành động toàn cục
    },
    step2: {
      use: 'processDataAction', // Tham chiếu hành động cấp mô hình
    }
  }
});

#Mô tả thuộc tính

#name

Kiểu: string
Bắt buộc: Có
Mô tả: Định danh duy nhất cho hành động

Dùng để tham chiếu hành động trong một bước thông qua thuộc tính use.

Ví dụ:

name: 'loadDataAction'
name: 'processDataAction'
name: 'saveDataAction'

#title

Kiểu: string
Bắt buộc: Không
Mô tả: Tiêu đề hiển thị của hành động

Dùng cho việc hiển thị trên giao diện người dùng và gỡ lỗi.

Ví dụ:

title: 'Load Data'
title: 'Process Information'
title: 'Save Results'

#handler

Kiểu: (ctx: TCtx, params: any) => Promise<any> | any
Bắt buộc: Có
Mô tả: Hàm xử lý cho hành động

Đây là logic cốt lõi của hành động, nhận vào ngữ cảnh và các tham số, sau đó trả về kết quả xử lý.

Ví dụ:

handler: async (ctx, params) => {
  const { model, flowEngine } = ctx;
  
  try {
    // Thực thi logic cụ thể
    const result = await performAction(params);
    
    // Trả về kết quả
    return {
      success: true,
      data: result,
      message: 'Action completed successfully'
    };
  } catch (error) {
    return {
      success: false,
      error: error.message
    };
  }
}

#defaultParams

Kiểu: Record<string, any> | ((ctx: TCtx) => Record<string, any> | Promise<Record<string, any>>)
Bắt buộc: Không
Mô tả: Các tham số mặc định cho hành động

Điền các giá trị mặc định cho tham số trước khi hành động được thực thi.

Ví dụ:

// Tham số mặc định tĩnh
defaultParams: {
  timeout: 5000,
  retries: 3,
  format: 'json'
}

// Tham số mặc định động
defaultParams: (ctx) => {
  return {
    userId: ctx.model.uid,
    timestamp: Date.now(),
    version: ctx.flowEngine.version
  }
}

// Tham số mặc định bất đồng bộ
defaultParams: async (ctx) => {
  const config = await loadConfiguration();
  return {
    apiUrl: config.apiUrl,
    apiKey: config.apiKey,
    timeout: config.timeout
  }
}

#uiSchema

Kiểu: Record<string, ISchema> | ((ctx: TCtx) => Record<string, ISchema> | Promise<Record<string, ISchema>>)
Bắt buộc: Không
Mô tả: Schema cấu hình giao diện người dùng (UI) cho hành động

Định nghĩa cách hành động được hiển thị trong UI và cấu hình biểu mẫu của nó.

Ví dụ:

uiSchema: {
  'x-component': 'Form',
  'x-component-props': {
    layout: 'vertical',
    labelCol: { span: 6 },
    wrapperCol: { span: 18 }
  },
  properties: {
    url: {
      type: 'string',
      title: 'API URL',
      'x-component': 'Input',
      'x-decorator': 'FormItem',
      required: true
    },
    method: {
      type: 'string',
      title: 'HTTP Method',
      'x-component': 'Select',
      'x-decorator': 'FormItem',
      enum: ['GET', 'POST', 'PUT', 'DELETE'],
      default: 'GET'
    },
    timeout: {
      type: 'number',
      title: 'Timeout (ms)',
      'x-component': 'InputNumber',
      'x-decorator': 'FormItem',
      default: 5000
    }
  }
}

#beforeParamsSave

Kiểu: (ctx: FlowSettingsContext<TModel>, params: any, previousParams: any) => void | Promise<void>
Bắt buộc: Không
Mô tả: Hàm hook được thực thi trước khi lưu tham số

Được thực thi trước khi các tham số của hành động được lưu, có thể dùng để xác thực hoặc chuyển đổi tham số.

Ví dụ:

beforeParamsSave: (ctx, params, previousParams) => {
  // Xác thực tham số
  if (!params.url) {
    throw new Error('URL is required');
  }
  
  // Chuyển đổi tham số
  params.url = params.url.trim();
  if (!params.url.startsWith('http')) {
    params.url = 'https://' + params.url;
  }
  
  // Ghi lại thay đổi
  console.log('Parameters changed:', {
    from: previousParams,
    to: params
  });
}

#afterParamsSave

Kiểu: (ctx: FlowSettingsContext<TModel>, params: any, previousParams: any) => void | Promise<void>
Bắt buộc: Không
Mô tả: Hàm hook được thực thi sau khi lưu tham số

Được thực thi sau khi các tham số của hành động được lưu, có thể dùng để kích hoạt các thao tác khác.

Ví dụ:

afterParamsSave: (ctx, params, previousParams) => {
  // Ghi nhật ký
  console.log('Action params saved:', params);
  
  // Kích hoạt sự kiện
  ctx.model.emitter.emit('actionParamsChanged', {
    actionName: 'loadDataAction',
    params,
    previousParams
  });
  
  // Cập nhật bộ nhớ đệm
  ctx.model.updateCache('actionParams', params);
}

#useRawParams

Kiểu: boolean | ((ctx: TCtx) => boolean | Promise<boolean>)
Bắt buộc: Không
Mô tả: Có sử dụng tham số thô hay không

Nếu là true, các tham số thô sẽ được truyền trực tiếp đến hàm xử lý mà không qua bất kỳ quá trình xử lý nào.

Ví dụ:

// Cấu hình tĩnh
useRawParams: true

// Cấu hình động
useRawParams: (ctx) => {
  return ctx.model.isDebugMode;
}

#uiMode

Kiểu: StepUIMode | ((ctx: FlowRuntimeContext<TModel>) => StepUIMode | Promise<StepUIMode>)
Bắt buộc: Không
Mô tả: Chế độ hiển thị UI cho hành động

Kiểm soát cách hành động được hiển thị trong UI.

Các chế độ được hỗ trợ:

  • 'dialog' - Chế độ hộp thoại
  • 'drawer' - Chế độ ngăn kéo
  • 'embed' - Chế độ nhúng
  • hoặc một đối tượng cấu hình tùy chỉnh

Ví dụ:

// Chế độ đơn giản
uiMode: 'dialog'

// Cấu hình tùy chỉnh
uiMode: {
  type: 'dialog',
  props: {
    width: 800,
    title: 'Action Configuration',
    maskClosable: false
  }
}

// Chế độ động
uiMode: (ctx) => {
  return ctx.model.isMobile ? 'drawer' : 'dialog';
}

#scene

Kiểu: ActionScene | ActionScene[]
Bắt buộc: Không
Mô tả: Các kịch bản sử dụng cho hành động

Giới hạn hành động chỉ được sử dụng trong các kịch bản cụ thể.

Các kịch bản được hỗ trợ:

  • 'settings' - Kịch bản cài đặt
  • 'runtime' - Kịch bản thời gian chạy
  • 'design' - Kịch bản thời gian thiết kế

Ví dụ:

scene: 'settings'  // Chỉ sử dụng trong kịch bản cài đặt
scene: ['settings', 'runtime']  // Sử dụng trong kịch bản cài đặt và thời gian chạy

#sort

Kiểu: number
Bắt buộc: Không
Mô tả: Trọng số sắp xếp cho hành động

Dùng để kiểm soát thứ tự hiển thị của hành động trong danh sách. Giá trị càng nhỏ thì vị trí càng cao (hiển thị trước).

Ví dụ:

sort: 0  // Vị trí cao nhất
sort: 10 // Vị trí trung bình
sort: 100 // Vị trí thấp hơn

#Ví dụ đầy đủ

class DataProcessingModel extends FlowModel {}

// Đăng ký hành động tải dữ liệu
DataProcessingModel.registerAction({
  name: 'loadDataAction',
  title: 'Load Data',
  handler: async (ctx, params) => {
    const { url, method = 'GET', timeout = 5000 } = params;
    
    try {
      const response = await fetch(url, {
        method,
        timeout,
        headers: {
          'Content-Type': 'application/json'
        }
      });
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      
      const data = await response.json();
      
      return {
        success: true,
        data,
        message: 'Data loaded successfully'
      };
    } catch (error) {
      return {
        success: false,
        error: error.message
      };
    }
  },
  defaultParams: {
    method: 'GET',
    timeout: 5000
  },
  uiSchema: {
    'x-component': 'Form',
    properties: {
      url: {
        type: 'string',
        title: 'API URL',
        'x-component': 'Input',
        'x-decorator': 'FormItem',
        required: true
      },
      method: {
        type: 'string',
        title: 'HTTP Method',
        'x-component': 'Select',
        'x-decorator': 'FormItem',
        enum: ['GET', 'POST', 'PUT', 'DELETE']
      },
      timeout: {
        type: 'number',
        title: 'Timeout (ms)',
        'x-component': 'InputNumber',
        'x-decorator': 'FormItem'
      }
    }
  },
  beforeParamsSave: (ctx, params) => {
    if (!params.url) {
      throw new Error('URL is required');
    }
    params.url = params.url.trim();
  },
  afterParamsSave: (ctx, params) => {
    ctx.model.emitter.emit('dataSourceChanged', params);
  },
  uiMode: 'dialog',
  scene: ['settings', 'runtime'],
  sort: 0
});

// Đăng ký hành động xử lý dữ liệu
DataProcessingModel.registerAction({
  name: 'processDataAction',
  title: 'Process Data',
  handler: async (ctx, params) => {
    const { data, processor, options = {} } = params;
    
    try {
      const processedData = await processData(data, processor, options);
      
      return {
        success: true,
        data: processedData,
        message: 'Data processed successfully'
      };
    } catch (error) {
      return {
        success: false,
        error: error.message
      };
    }
  },
  defaultParams: (ctx) => ({
    processor: 'default',
    options: {
      format: 'json',
      encoding: 'utf8'
    }
  }),
  uiSchema: {
    'x-component': 'Form',
    properties: {
      processor: {
        type: 'string',
        title: 'Processor',
        'x-component': 'Select',
        'x-decorator': 'FormItem',
        enum: ['default', 'advanced', 'custom']
      },
      options: {
        type: 'object',
        title: 'Options',
        'x-component': 'Form',
        'x-decorator': 'FormItem',
        properties: {
          format: {
            type: 'string',
            title: 'Format',
            'x-component': 'Select',
            enum: ['json', 'xml', 'csv']
          },
          encoding: {
            type: 'string',
            title: 'Encoding',
            'x-component': 'Select',
            enum: ['utf8', 'ascii', 'latin1']
          }
        }
      }
    }
  },
  scene: 'runtime',
  sort: 1
});