# 工作流前端对接文档

## 一、系统架构

### 1.1 整体架构
```typescript
// 系统分层
interface SystemArchitecture {
    presentation: {
        views: '页面组件',      // 负责页面展示和用户交互
        components: '通用组件',  // 可复用的UI组件
        hooks: '业务钩子',      // 封装业务逻辑的Hooks
    };
    domain: {
        models: '数据模型',     // 核心业务模型定义
        services: '领域服务',   // 业务逻辑封装
        stores: '状态管理',     // 全局状态管理
    };
    infrastructure: {
        api: 'API封装',        // 后端接口调用
        utils: '工具函数',      // 通用工具方法
        constants: '常量定义',  // 系统常量
    };
}
```

### 1.2 核心模块
1. **工作流设计器**
   - 负责工作流的可视化设计
   - 节点拖拽和连线
   - 属性配置面板
   - 数据验证和保存

2. **表单设计器**
   - 工作流表单的可视化设计
   - 字段配置和验证规则
   - 布局设计
   - 表单预览

3. **工作流引擎**
   - 工作流实例管理
   - 节点状态控制
   - 变量管理
   - 日志记录

## 二、数据模型

### 2.1 工作流定义
```typescript
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 工作流实例
```typescript
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 工作流定义接口
```typescript
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 工作流实例接口
```typescript
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 工作流设计器
```typescript
// 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 表单设计器
```typescript
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 工作流设计器状态
```typescript
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 工作流实例状态
```typescript
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 基础使用
```typescript
// 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 节点配置示例
```typescript
// 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-projectGroup-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 数据验证示例
```typescript
// 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 性能优化
1. **大数据量处理**
   - 使用虚拟滚动
   - 分页加载数据
   - 按需渲染节点

2. **状态管理**
   - 合理使用缓存
   - 避免频繁更新
   - 使用不可变数据

3. **渲染优化**
   - 组件懒加载
   - 合理使用memo
   - 避免不必要的重渲染

### 7.2 错误处理
1. **前端验证**
   - 实时验证
   - 提供错误提示
   - 防止无效操作

2. **异常捕获**
   - 全局错误处理
   - 友好的错误提示
   - 错误日志记录

3. **数据恢复**
   - 自动保存
   - 本地缓存
   - 操作回滚

### 7.3 用户体验
1. **交互设计**
   - 拖拽操作流畅
   - 实时预览效果
   - 快捷键支持

2. **反馈机制**
   - 操作提示
   - 加载状态
   - 成功/失败反馈

3. **辅助功能**
   - 自动布局
   - 查找/替换
   - 导入/导出

## 八、常见问题

### 8.1 配置相关
1. **节点配置问题**
   - Q: 如何处理不同类型节点的配置？
   - A: 使用统一的配置接口，通过类型区分不同的配置表单

2. **数据同步问题**
   - Q: 如何保持前端展示数据与后端数据一致？
   - A: 实现定期自动保存和加载机制

3. **验证问题**
   - Q: 如何确保工作流数据的正确性？
   - A: 实现多层次的验证机制，包括实时验证和提交验证

### 8.2 性能相关
1. **大型工作流**
   - Q: 如何处理节点数量很多的工作流？
   - A: 实现分区渲染和虚拟滚动

2. **频繁操作**
   - Q: 如何处理频繁的拖拽和连线操作？
   - A: 使用节流和防抖优化性能

3. **数据量大**
   - Q: 如何处理大量的历史数据？
   - A: 实现分页加载和懒加载机制

## 九、开发规范

### 9.1 代码规范
1. **命名规范**
   - 组件使用大驼峰命名
   - 方法使用小驼峰命名
   - 常量使用大写下划线

2. **注释规范**
   - 组件必须有文档注释
   - 复杂逻辑需要注释
   - 保持注释的及时更新

3. **类型规范**
   - 使用TypeScript
   - 定义清晰的接口
   - 避免any类型

### 9.2 提交规范
1. **提交信息**
   - feat: 新功能
   - fix: 修复bug
   - docs: 文档更新
   - style: 代码格式
   - refactor: 重构
   - test: 测试
   - chore: 构建过程或辅助工具的变动

2. **分支管理**
   - master: 主分支
   - develop: 开发分支
   - feature: 功能分支
   - hotfix: 紧急修复分支

### 9.3 测试规范
1. **单元测试**
   - 组件测试
   - 方法测试
   - 工具函数测试

2. **集成测试**
   - 流程测试
   - 接口测试
   - 兼容性测试

3. **E2E测试**
   - 用户操作测试
   - 场景测试
   - 性能测试