869 lines
23 KiB
Markdown
869 lines
23 KiB
Markdown
# 工作流前端对接文档
|
||
|
||
## 一、系统架构
|
||
|
||
### 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测试**
|
||
- 用户操作测试
|
||
- 场景测试
|
||
- 性能测试 |