23 KiB
23 KiB
工作流前端对接文档
一、系统架构
1.1 整体架构
// 系统分层
interface SystemArchitecture {
presentation: {
views: '页面组件', // 负责页面展示和用户交互
components: '通用组件', // 可复用的UI组件
hooks: '业务钩子', // 封装业务逻辑的Hooks
};
domain: {
models: '数据模型', // 核心业务模型定义
services: '领域服务', // 业务逻辑封装
stores: '状态管理', // 全局状态管理
};
infrastructure: {
api: 'API封装', // 后端接口调用
utils: '工具函数', // 通用工具方法
constants: '常量定义', // 系统常量
};
}
1.2 核心模块
-
工作流设计器
- 负责工作流的可视化设计
- 节点拖拽和连线
- 属性配置面板
- 数据验证和保存
-
表单设计器
- 工作流表单的可视化设计
- 字段配置和验证规则
- 布局设计
- 表单预览
-
工作流引擎
- 工作流实例管理
- 节点状态控制
- 变量管理
- 日志记录
二、数据模型
2.1 工作流定义
interface WorkflowDefinition {
// 基本信息
id: number; // 工作流定义ID
code: string; // 工作流编码(唯一标识)
name: string; // 工作流名称
description: string; // 工作流描述
version: number; // 版本号
status: WorkflowStatus; // 状态(DRAFT/PUBLISHED/DISABLED)
enabled: boolean; // 是否启用
// 节点定义
nodes: Array<{
id: number; // 节点定义ID
nodeId: string; // 节点标识(在图中的唯一标识)
name: string; // 节点名称
type: NodeType; // 节点类型(START/END/TASK/GATEWAY)
config: string; // 节点配置(JSON字符串)
description: string; // 节点描述
orderNum: number; // 排序号
}>;
// 配置数据
nodeConfig: string; // 节点关系配置(JSON字符串)
transitionConfig: string; // 流转配置(JSON字符串)
formDefinition: string; // 表单定义(JSON字符串)
graphDefinition: string; // 图形布局(JSON字符串)
}
// 节点配置示例(JSON格式)
interface NodeConfig {
// 开始节点配置
startNode: {
type: 'START';
name: string;
config?: Record<string, any>;
};
// 任务节点配置
taskNodes: Array<{
id: string;
type: 'TASK';
name: string;
executor?: string; // 执行器类型
config: {
// Shell执行器配置
script?: string; // 脚本内容
timeout?: number; // 超时时间
workingDir?: string; // 工作目录
// Jenkins执行器配置
jenkinsJob?: string; // Jenkins任务名
parameters?: Record<string, any>; // 构建参数
};
}>;
// 网关节点配置
gatewayNodes: Array<{
id: string;
type: 'GATEWAY';
name: string;
gatewayType: 'EXCLUSIVE' | 'PARALLEL' | 'INCLUSIVE'; // 网关类型
conditions?: Array<{
expression: string; // 条件表达式
description: string; // 条件描述
}>;
}>;
// 结束节点配置
endNode: {
type: 'END';
name: string;
config?: Record<string, any>;
};
}
// 流转配置示例
interface TransitionConfig {
transitions: Array<{
from: string; // 源节点ID
to: string; // 目标节点ID
condition?: string; // 流转条件(网关节点使用)
priority?: number; // 优先级(条件分支使用)
}>;
}
// 图形布局示例
interface GraphDefinition {
nodes: Array<{
id: string; // 节点ID
type: string; // 节点类型
x: number; // X坐标
y: number; // Y坐标
properties?: { // 节点属性
width?: number;
height?: number;
color?: string;
icon?: string;
};
}>;
edges: Array<{
source: string; // 源节点ID
target: string; // 目标节点ID
points?: Array<{ // 连线控制点
x: number;
y: number;
}>;
properties?: { // 连线属性
style?: string;
arrow?: string;
label?: string;
};
}>;
}
2.2 工作流实例
interface WorkflowInstance {
id: number; // 实例ID
definitionId: number; // 工作流定义ID
businessKey: string; // 业务标识
status: InstanceStatus; // 状态
startTime: string; // 开始时间
endTime: string; // 结束时间
variables: string; // 工作流变量(JSON字符串)
error: string; // 错误信息
}
interface NodeInstance {
id: number; // 实例ID
workflowInstanceId: number; // 工作流实例ID
nodeId: string; // 节点ID
nodeType: NodeType; // 节点类型
status: NodeStatus; // 节点状态
startTime: string; // 开始时间
endTime: string; // 结束时间
input: string; // 输入参数(JSON字符串)
output: string; // 输出结果(JSON字符串)
error: string; // 错误信息
}
三、接口定义
3.1 工作流定义接口
interface WorkflowDefinitionAPI {
// 基础CRUD
create: {
url: '/api/v1/workflow-definitions',
method: 'POST',
data: WorkflowDefinitionDTO,
response: Response<WorkflowDefinitionDTO>
};
update: {
url: '/api/v1/workflow-definitions/{id}',
method: 'PUT',
data: WorkflowDefinitionDTO,
response: Response<WorkflowDefinitionDTO>
};
delete: {
url: '/api/v1/workflow-definitions/{id}',
method: 'DELETE',
response: Response<void>
};
getById: {
url: '/api/v1/workflow-definitions/{id}',
method: 'GET',
response: Response<WorkflowDefinitionDTO>
};
page: {
url: '/api/v1/workflow-definitions/page',
method: 'GET',
params: PageQuery,
response: Response<Page<WorkflowDefinitionDTO>>
};
// 特殊操作
publish: {
url: '/api/v1/workflow-definitions/{id}/publish',
method: 'POST',
response: Response<WorkflowDefinitionDTO>
};
disable: {
url: '/api/v1/workflow-definitions/{id}/disable',
method: 'POST',
response: Response<WorkflowDefinitionDTO>
};
enable: {
url: '/api/v1/workflow-definitions/{id}/enable',
method: 'POST',
response: Response<WorkflowDefinitionDTO>
};
}
3.2 工作流实例接口
interface WorkflowInstanceAPI {
// 实例操作
start: {
url: '/api/v1/workflow-instances/start',
method: 'POST',
data: {
workflowCode: string; // 工作流编码
businessKey: string; // 业务标识
variables?: Record<string, any>; // 工作流变量
},
response: Response<WorkflowInstanceDTO>
};
terminate: {
url: '/api/v1/workflow-instances/{id}/terminate',
method: 'POST',
data: {
reason?: string; // 终止原因
},
response: Response<void>
};
pause: {
url: '/api/v1/workflow-instances/{id}/pause',
method: 'POST',
response: Response<void>
};
resume: {
url: '/api/v1/workflow-instances/{id}/resume',
method: 'POST',
response: Response<void>
};
// 查询接口
getById: {
url: '/api/v1/workflow-instances/{id}',
method: 'GET',
response: Response<WorkflowInstanceDTO>
};
page: {
url: '/api/v1/workflow-instances/page',
method: 'GET',
params: PageQuery & {
status?: InstanceStatus;
startTime?: string;
endTime?: string;
keyword?: string;
},
response: Response<Page<WorkflowInstanceDTO>>
};
}
四、组件设计
4.1 工作流设计器
// 1. 设计器组件
interface WorkflowDesigner {
// 属性定义
props: {
value?: WorkflowDefinition; // 工作流定义数据
readOnly?: boolean; // 是否只读
onChange?: (value: WorkflowDefinition) => void; // 数据变更回调
};
// 子组件
components: {
ToolBar: '工具栏', // 撤销、重做、缩放等操作
NodePanel: '节点面板', // 可用节点列表
Canvas: '画布', // 节点拖拽和连线
ConfigPanel: '配置面板', // 节点和连线配置
MiniMap: '小地图' // 导航缩略图
};
// 核心方法
methods: {
// 初始化设计器
initialize(definition: WorkflowDefinition): void;
// 添加节点
addNode(nodeData: NodeData): void;
// 连接节点
connect(source: string, target: string): void;
// 更新节点配置
updateNodeConfig(nodeId: string, config: any): void;
// 更新连线配置
updateEdgeConfig(edgeId: string, config: any): void;
// 验证数据
validate(): ValidationResult;
// 导出数据
exportData(): WorkflowDefinition;
};
}
// 2. 节点配置面板
interface NodeConfigPanel {
props: {
node: NodeData; // 节点数据
nodeType: NodeType; // 节点类型
onChange: (config: any) => void; // 配置变更回调
};
// 配置表单定义
forms: {
// 基础配置(所有节点都有)
BaseConfig: {
name: string; // 节点名称
description?: string; // 节点描述
};
// 任务节点配置
TaskConfig: {
executor: string; // 执行器类型
config: Record<string, any>; // 执行器配置
};
// 网关节点配置
GatewayConfig: {
type: 'EXCLUSIVE' | 'PARALLEL' | 'INCLUSIVE';
conditions?: Array<{
expression: string;
description: string;
}>;
};
};
}
// 3. 连线配置面板
interface EdgeConfigPanel {
props: {
edge: EdgeData; // 连线数据
sourceNode: NodeData; // 源节点
targetNode: NodeData; // 目标节点
onChange: (config: any) => void; // 配置变更回调
};
// 配置表单定义
forms: {
condition?: string; // 流转条件
priority?: number; // 优先级
description?: string; // 说明
};
}
4.2 表单设计器
interface FormDesigner {
props: {
value?: FormDefinition; // 表单定义数据
onChange?: (value: FormDefinition) => void; // 数据变更回调
};
// 可用的字段类型
fieldTypes: {
input: '单行文本',
textarea: '多行文本',
number: '数字',
select: '下拉选择',
radio: '单选',
checkbox: '多选',
date: '日期',
datetime: '日期时间',
file: '文件上传'
};
// 字段属性定义
fieldProperties: {
name: string; // 字段名
label: string; // 字段标签
type: string; // 字段类型
required?: boolean; // 是否必填
defaultValue?: any; // 默认值
placeholder?: string; // 占位提示
description?: string; // 字段描述
options?: Array<{ // 选项(用于select/radio/checkbox)
label: string;
value: any;
}>;
validation?: Array<{ // 验证规则
type: string; // 规则类型
message: string; // 错误消息
params?: any; // 规则参数
}>;
};
}
五、状态管理
5.1 工作流设计器状态
interface DesignerState {
// 画布状态
canvas: {
scale: number; // 缩放比例
position: { // 画布位置
x: number;
y: number;
};
selectedElements: { // 选中的元素
nodes: string[]; // 节点ID列表
edges: string[]; // 连线ID列表
};
};
// 历史记录
history: {
undoStack: HistoryItem[]; // 撤销栈
redoStack: HistoryItem[]; // 重做栈
canUndo: boolean; // 是否可撤销
canRedo: boolean; // 是否可重做
};
// 节点数据
nodes: Record<string, NodeData>; // 节点数据映射
edges: Record<string, EdgeData>; // 连线数据映射
// 配置面板
configPanel: {
visible: boolean; // 是否显示
type: 'node' | 'edge'; // 配置类型
elementId?: string; // 当前配置的元素ID
};
}
5.2 工作流实例状态
interface InstanceState {
// 实例数据
instance: {
current?: WorkflowInstance; // 当前实例
nodes: NodeInstance[]; // 节点实例列表
variables: Record<string, any>; // 工作流变量
};
// 操作权限
permissions: {
canTerminate: boolean; // 是否可终止
canPause: boolean; // 是否可暂停
canResume: boolean; // 是否可恢复
};
// 日志数据
logs: {
workflow: WorkflowLog[]; // 工作流日志
nodes: Record<string, NodeLog[]>; // 节点日志
};
}
六、工作流设计器使用示例
6.1 基础使用
// 1. 创建工作流
const createWorkflow = async (definition: WorkflowDefinition) => {
try {
// 验证数据
const validationResult = workflowDesigner.validate();
if (!validationResult.valid) {
message.error('工作流数据验证失败:' + validationResult.errors.join(', '));
return;
}
// 提交数据
const response = await WorkflowDefinitionAPI.create(definition);
if (response.code === 200) {
message.success('工作流创建成功');
return response.data;
} else {
message.error('工作流创建失败:' + response.message);
}
} catch (error) {
message.error('系统错误:' + error.message);
}
};
// 2. 加载工作流
const loadWorkflow = async (id: number) => {
try {
const response = await WorkflowDefinitionAPI.getById(id);
if (response.code === 200) {
// 初始化设计器
workflowDesigner.initialize(response.data);
return response.data;
} else {
message.error('加载工作流失败:' + response.message);
}
} catch (error) {
message.error('系统错误:' + error.message);
}
};
// 3. 保存工作流
const saveWorkflow = async (id: number) => {
try {
// 获取设计器数据
const definition = workflowDesigner.exportData();
// 验证数据
const validationResult = workflowDesigner.validate();
if (!validationResult.valid) {
message.error('工作流数据验证失败:' + validationResult.errors.join(', '));
return;
}
// 提交数据
const response = await WorkflowDefinitionAPI.update(id, definition);
if (response.code === 200) {
message.success('工作流保存成功');
return response.data;
} else {
message.error('工作流保存失败:' + response.message);
}
} catch (error) {
message.error('系统错误:' + error.message);
}
};
6.2 节点配置示例
// 1. Shell节点配置
const ShellNodeConfig = {
type: 'TASK',
name: 'Shell脚本',
executor: 'SHELL',
config: {
script: '#!/bin/bash\necho "Hello World"',
timeout: 300,
workingDir: '/tmp'
}
};
// 2. Jenkins节点配置
const JenkinsNodeConfig = {
type: 'TASK',
name: 'Jenkins构建',
executor: 'JENKINS',
config: {
jenkinsJob: 'my-project-build',
parameters: {
BRANCH: 'master',
ENV: 'prod'
}
}
};
// 3. 网关节点配置
const GatewayNodeConfig = {
type: 'GATEWAY',
name: '条件分支',
gatewayType: 'EXCLUSIVE',
conditions: [
{
expression: '${status} == "SUCCESS"',
description: '执行成功'
},
{
expression: '${status} == "FAILED"',
description: '执行失败'
}
]
};
6.3 数据验证示例
// 1. 节点配置验证
const validateNodeConfig = (node: NodeData): ValidationResult => {
const errors: string[] = [];
// 基础验证
if (!node.name) {
errors.push('节点名称不能为空');
}
// 任务节点特殊验证
if (node.type === 'TASK') {
if (!node.executor) {
errors.push('请选择执行器');
}
// Shell执行器验证
if (node.executor === 'SHELL') {
if (!node.config.script) {
errors.push('脚本内容不能为空');
}
}
// Jenkins执行器验证
if (node.executor === 'JENKINS') {
if (!node.config.jenkinsJob) {
errors.push('Jenkins任务名不能为空');
}
}
}
// 网关节点特殊验证
if (node.type === 'GATEWAY') {
if (!node.gatewayType) {
errors.push('请选择网关类型');
}
if (node.gatewayType === 'EXCLUSIVE' && (!node.conditions || node.conditions.length === 0)) {
errors.push('请配置分支条件');
}
}
return {
valid: errors.length === 0,
errors
};
};
// 2. 流程验证
const validateWorkflow = (definition: WorkflowDefinition): ValidationResult => {
const errors: string[] = [];
// 1. 基础信息验证
if (!definition.name) {
errors.push('工作流名称不能为空');
}
if (!definition.code) {
errors.push('工作流编码不能为空');
}
// 2. 节点验证
const nodes = JSON.parse(definition.nodeConfig);
// 验证开始节点
if (!nodes.startNode) {
errors.push('必须有一个开始节点');
}
// 验证结束节点
if (!nodes.endNode) {
errors.push('必须有一个结束节点');
}
// 验证任务节点
if (!nodes.taskNodes || nodes.taskNodes.length === 0) {
errors.push('至少需要一个任务节点');
}
// 3. 连线验证
const transitions = JSON.parse(definition.transitionConfig).transitions;
// 验证是否有孤立节点
const connectedNodes = new Set<string>();
transitions.forEach(t => {
connectedNodes.add(t.from);
connectedNodes.add(t.to);
});
const allNodes = [
nodes.startNode,
...nodes.taskNodes,
...(nodes.gatewayNodes || []),
nodes.endNode
];
allNodes.forEach(node => {
if (!connectedNodes.has(node.id)) {
errors.push(`节点 ${node.name}(${node.id}) 未连接`);
}
});
// 4. 验证是否有环
if (hasCircle(transitions)) {
errors.push('流程中存在循环');
}
return {
valid: errors.length === 0,
errors
};
};
七、最佳实践
7.1 性能优化
-
大数据量处理
- 使用虚拟滚动
- 分页加载数据
- 按需渲染节点
-
状态管理
- 合理使用缓存
- 避免频繁更新
- 使用不可变数据
-
渲染优化
- 组件懒加载
- 合理使用memo
- 避免不必要的重渲染
7.2 错误处理
-
前端验证
- 实时验证
- 提供错误提示
- 防止无效操作
-
异常捕获
- 全局错误处理
- 友好的错误提示
- 错误日志记录
-
数据恢复
- 自动保存
- 本地缓存
- 操作回滚
7.3 用户体验
-
交互设计
- 拖拽操作流畅
- 实时预览效果
- 快捷键支持
-
反馈机制
- 操作提示
- 加载状态
- 成功/失败反馈
-
辅助功能
- 自动布局
- 查找/替换
- 导入/导出
八、常见问题
8.1 配置相关
-
节点配置问题
- Q: 如何处理不同类型节点的配置?
- A: 使用统一的配置接口,通过类型区分不同的配置表单
-
数据同步问题
- Q: 如何保持前端展示数据与后端数据一致?
- A: 实现定期自动保存和加载机制
-
验证问题
- Q: 如何确保工作流数据的正确性?
- A: 实现多层次的验证机制,包括实时验证和提交验证
8.2 性能相关
-
大型工作流
- Q: 如何处理节点数量很多的工作流?
- A: 实现分区渲染和虚拟滚动
-
频繁操作
- Q: 如何处理频繁的拖拽和连线操作?
- A: 使用节流和防抖优化性能
-
数据量大
- Q: 如何处理大量的历史数据?
- A: 实现分页加载和懒加载机制
九、开发规范
9.1 代码规范
-
命名规范
- 组件使用大驼峰命名
- 方法使用小驼峰命名
- 常量使用大写下划线
-
注释规范
- 组件必须有文档注释
- 复杂逻辑需要注释
- 保持注释的及时更新
-
类型规范
- 使用TypeScript
- 定义清晰的接口
- 避免any类型
9.2 提交规范
-
提交信息
- feat: 新功能
- fix: 修复bug
- docs: 文档更新
- style: 代码格式
- refactor: 重构
- test: 测试
- chore: 构建过程或辅助工具的变动
-
分支管理
- master: 主分支
- develop: 开发分支
- feature: 功能分支
- hotfix: 紧急修复分支
9.3 测试规范
-
单元测试
- 组件测试
- 方法测试
- 工具函数测试
-
集成测试
- 流程测试
- 接口测试
- 兼容性测试
-
E2E测试
- 用户操作测试
- 场景测试
- 性能测试