This commit is contained in:
dengqichen 2025-10-20 15:05:47 +08:00
parent 2c66fed29a
commit b26216a619
23 changed files with 11 additions and 1044 deletions

View File

@ -1,201 +0,0 @@
# 🎉 架构迁移完成报告 - Design 模块提升
## ✅ 迁移执行状态:成功完成!
**执行时间**2025-10-20 14:48
**迁移类型**:模块架构重组 + 路由优化
## 🏗️ 架构变化对比
### 迁移前架构 ❌
```
Workflow/
├── Definition/
│ ├── Design/ # 复杂设计器13个文件172KB
│ │ ├── components/ # 5个UI组件
│ │ ├── hooks/ # 4个自定义Hook
│ │ ├── utils/ # 工具类和图形配置
│ │ └── index.tsx # 主组件
│ ├── index.tsx # 定义列表页面
│ └── service.ts # 定义管理API
├── Instance/
├── Monitor/
└── NodeDesign/
```
### 迁移后架构 ✅
```
Workflow/
├── Definition/ # ✨ 专注定义管理
│ ├── index.tsx # 工作流定义列表
│ ├── service.ts # 定义CRUD API
│ └── components/ # 编辑相关组件
├── Design/ # ✨ 独立设计器模块
│ ├── components/ # 5个UI组件
│ ├── hooks/ # 4个状态管理Hook
│ ├── utils/ # 图形工具和验证器
│ ├── index.tsx # 设计器主组件
│ └── service.ts # 设计器专用API
├── Instance/
├── Monitor/
└── NodeDesign/
```
## 🔄 路由变化
### 旧路由结构
```
/workflow/definition # 定义列表
/workflow/definition/:id/design # 设计器(嵌套路由)
```
### 新路由结构
```
/workflow/definition # 定义列表
/workflow/design/:id # 设计器(平级路由)
```
## 📋 执行的操作
### 1. 文件迁移 ✅
```bash
# 复制整个 Design 目录到新位置
robocopy Definition\Design Design /E
# 27个文件172KB复制成功
# 删除原来的 Design 目录
Remove-Item Definition\Design -Recurse -Force
```
### 2. 路由重构 ✅
```typescript
// 更新路由导入
const WorkflowDesign = lazy(() => import('../pages/Workflow/Design'));
// 重构路由结构
{
path: 'definition',
element: <WorkflowDefinitionList/> // 简化为单页面
},
{
path: 'design',
children: [{
path: ':id',
element: <WorkflowDesign/>
}]
}
```
### 3. 导入路径修复 ✅
```typescript
// NodePanel.tsx
import {getNodeDefinitionList} from "../service";
// useWorkflowData.ts
import { getDefinitionDetail, saveDefinition } from '../../Definition/service';
```
### 4. 跳转链接更新 ✅
```typescript
// Definition/index.tsx
const handleDesignFlow = (record: WorkflowDefinition) => {
navigate(`/workflow/design/${record.id}`); // 新路径
};
```
## 🎯 架构优势提升
### 1. 模块独立性 ⬆️
- **Before**: Design 作为 Definition 子模块,耦合度高
- **After**: Design 独立模块,职责单一
### 2. 路由语义化 ⬆️
- **Before**: `/workflow/definition/3/design` - 嵌套复杂
- **After**: `/workflow/design/3` - 简洁直观
### 3. 团队协作 ⬆️
- **Before**: 修改设计器影响定义模块
- **After**: 两个模块完全独立开发
### 4. 扩展性 ⬆️
- **Before**: 受 Definition 模块限制
- **After**: 可独立演进和扩展
## 📊 迁移数据统计
| 指标 | 数量 | 状态 |
|------|------|------|
| **迁移文件数** | 27个 | ✅ 成功 |
| **迁移数据量** | 172KB | ✅ 完整 |
| **路由更新** | 2处 | ✅ 完成 |
| **导入修复** | 2处 | ✅ 完成 |
| **linter错误** | 0个 | ✅ 清洁 |
## 🚀 新的访问方式
### 工作流定义管理
```
http://localhost:3000/workflow/definition
```
### 工作流设计器
```
http://localhost:3000/workflow/design/3
```
## 🧪 验证清单
请验证以下功能:
### 定义管理页面
- [ ] 列表正常显示
- [ ] "设计"按钮跳转正确
- [ ] 编辑功能正常
### 设计器页面
- [ ] 通过新路径正常访问
- [ ] 所有功能正常工作
- [ ] 保存功能正常
- [ ] 返回按钮跳转正确
## 📈 架构成熟度提升
| 维度 | 迁移前 | 迁移后 | 提升 |
|------|--------|--------|------|
| **模块独立性** | 3/10 | 9/10 | +200% |
| **路由清晰度** | 4/10 | 9/10 | +125% |
| **可维护性** | 5/10 | 9/10 | +80% |
| **扩展性** | 4/10 | 9/10 | +125% |
| **团队协作** | 5/10 | 9/10 | +80% |
## 🎊 架构重组成就
- 🏗️ **模块架构师**: 成功重组复杂模块结构
- 🛣️ **路由优化专家**: 简化路由层次和语义
- 🔧 **依赖管理大师**: 精确修复所有导入路径
- 🚀 **系统演进推动者**: 提升整体架构成熟度
- 👥 **协作效率提升者**: 优化团队开发体验
## 📞 后续建议
1. **监控一段时间**:确保新架构稳定运行
2. **团队同步**:通知团队成员路径变化
3. **文档更新**:更新相关开发文档
4. **测试覆盖**:为新路由添加测试用例
---
**🎉 恭喜!你已经成功完成了从嵌套架构到平级模块的重大架构重组!**
**新的模块化架构将带来更好的开发体验和系统可维护性!** 🚀✨
## 🔮 未来演进方向
现在你有了完美的模块化架构基础,可以考虑:
1. **微前端架构**: 每个模块可独立部署
2. **组件库抽取**: 公共组件提升为独立库
3. **工作流引擎**: Design 模块可演进为独立的工作流引擎
4. **插件系统**: 支持第三方节点和扩展
架构重组完成!🎊

View File

@ -1,138 +0,0 @@
# 🐛 第二轮无限循环错误修复记录
## 问题描述
尽管修复了第一轮的无限循环问题,但页面仍然出现循环加载:
```
RefactoredIndex.tsx:68 开始加载工作流详情,节点定义已准备就绪
useWorkflowData.ts:58 正在还原节点: START_EVENT Object
... (重复执行多次)
```
## 🔍 问题根因分析
### 第二轮循环触发链
```
RefactoredIndex.tsx useEffect -> loadDefinitionDetail (未使用useCallback)
useWorkflowData -> loadDefinitionDetail 重新创建
RefactoredIndex.tsx useEffect 依赖项变化 -> 重新执行
回到第一步,形成无限循环
```
### 具体问题点
- `useWorkflowData.ts` 中的 `loadDefinitionDetail` 函数未使用 `useCallback` 记忆化
- `saveWorkflow` 函数也未使用 `useCallback` 记忆化
- `RefactoredIndex.tsx` 的 useEffect 依赖项包含了每次都重新创建的函数
## ✅ 修复方案
### 1. 记忆化 loadDefinitionDetail 函数
```typescript
// 修复前
const loadDefinitionDetail = async (graphInstance: Graph, definitionId: string) => {
// ...
};
// 修复后
const loadDefinitionDetail = useCallback(async (graphInstance: Graph, definitionId: string) => {
// ...
}, [nodeDefinitions]);
```
### 2. 记忆化 saveWorkflow 函数
```typescript
// 修复前
const saveWorkflow = async (graph: Graph) => {
// ...
};
// 修复后
const saveWorkflow = useCallback(async (graph: Graph) => {
// ...
}, [nodeDefinitions]);
```
### 3. 添加必要的依赖
- 导入 `useCallback` from 'react'
- 为 `useCallback` 函数添加正确的依赖数组
## 📋 修改文件清单
### 核心修复文件
- ✅ `src/pages/Workflow/Definition/Design/hooks/useWorkflowData.ts`
- 添加 `useCallback` 导入
- `loadDefinitionDetail` 函数使用 `useCallback` 包装,依赖 `[nodeDefinitions]`
- `saveWorkflow` 函数使用 `useCallback` 包装,依赖 `[nodeDefinitions]`
## 🧪 验证修复效果
### 1. 控制台检查
重新加载页面,应该只看到一次日志输出:
- ✅ `开始加载工作流详情,节点定义已准备就绪` - 只出现一次
- ✅ `正在还原节点: START_EVENT` - 每个节点只出现一次
- ✅ 无重复的无限循环日志
### 2. 功能验证
- ✅ 页面正常加载,不卡死
- ✅ 工作流图形正确显示
- ✅ 节点和连线正确恢复
- ✅ 所有交互功能正常
### 3. 性能检查
- ✅ CPU 使用率正常
- ✅ 内存使用稳定
- ✅ 页面响应流畅
## 🎯 循环依赖防范策略
为避免类似问题再次发生,建议:
### 1. 函数记忆化规则
```typescript
// 所有被作为依赖项的函数都应该使用 useCallback
const myFunction = useCallback(() => {
// ...
}, [appropriateDependencies]);
```
### 2. useEffect 依赖检查
```typescript
// 确保依赖项稳定
useEffect(() => {
// effect logic
}, [stableDependency1, stableDependency2]); // 确保这些值不会每次都变化
```
### 3. 开发时调试
```typescript
// 添加调试日志来跟踪函数创建
const loadDefinitionDetail = useCallback(async (...args) => {
console.log('loadDefinitionDetail called', args);
// ...
}, [nodeDefinitions]);
```
## 📊 修复前后对比
| 指标 | 修复前 | 修复后 |
|------|--------|--------|
| 页面加载 | ❌ 无限循环 | ✅ 正常加载 |
| 控制台日志 | ❌ 重复输出 | ✅ 单次输出 |
| CPU 使用 | ❌ 持续高占用 | ✅ 正常 |
| 用户体验 | ❌ 页面卡死 | ✅ 流畅交互 |
## 🏆 总结
通过这两轮修复,我们彻底解决了重构版本中的无限循环问题:
1. **第一轮**:修复了 `useWorkflowModals` 中事件处理函数的循环依赖
2. **第二轮**:修复了 `useWorkflowData` 中异步函数的循环依赖
重要经验:
- **useCallback 是必需的**:任何作为 useEffect 依赖的函数都必须记忆化
- **依赖数组很关键**:需要准确指定依赖,避免过度依赖或遗漏依赖
- **分层修复**:先修复明显的问题,然后处理隐藏的问题
现在重构版本应该可以正常工作了!🎉

View File

@ -1,122 +0,0 @@
# 🐛 无限循环错误修复记录
## 问题描述
```
Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
```
## 🔍 问题根因分析
### 1. 无限循环触发链
```
useWorkflowModals -> handleNodeEdit/handleEdgeEdit (每次渲染重新创建)
useWorkflowGraph -> useEffect 依赖项变化
setGraph -> 触发组件重新渲染
回到第一步,形成无限循环
```
### 2. 具体问题点
- `handleNodeEdit``handleEdgeEdit` 函数未使用 `useCallback` 记忆化
- `useWorkflowGraph` 的依赖数组包含每次都变化的函数引用
- Ref 对象不应该作为 useEffect 的依赖项
## ✅ 修复方案
### 1. 记忆化所有事件处理函数
```typescript
// useWorkflowModals.ts 修复
const handleNodeEdit = useCallback((cell: Cell, nodeDefinition?: NodeDefinitionResponse) => {
setSelectedNode(cell);
setSelectedNodeDefinition(nodeDefinition || null);
setConfigModalVisible(true);
}, []);
const handleEdgeEdit = useCallback((edge: Edge) => {
setSelectedEdge(edge);
setExpressionModalVisible(true);
}, []);
```
### 2. 优化依赖数组
```typescript
// useWorkflowGraph.ts 修复
// 移除不必要的 ref 依赖
}, [isNodeDefinitionsLoaded, nodeDefinitions, onNodeEdit, onEdgeEdit]);
```
### 3. 修复其他 useCallback 函数
所有涉及状态更新的函数都使用 `useCallback` 包装,避免不必要的重新创建。
## 🧪 验证修复效果
### 1. 控制台检查
重新加载页面,确认不再出现以下错误:
- ❌ `Maximum update depth exceeded`
- ❌ `Warning: Maximum update depth exceeded`
### 2. 功能测试
- ✅ 页面能正常加载
- ✅ 节点面板显示正常
- ✅ 拖拽功能正常
- ✅ 节点编辑功能正常
- ✅ 画布操作流畅
### 3. 性能检查
打开 React DevTools Profiler确认
- ✅ 组件渲染次数合理
- ✅ 没有不必要的重复渲染
- ✅ useEffect 执行次数正常
## 📋 修改文件清单
### 核心修复文件
- ✅ `src/pages/Workflow/Definition/Design/hooks/useWorkflowModals.ts`
- 添加 `useCallback` 导入
- 所有事件处理函数使用 `useCallback` 包装
- ✅ `src/pages/Workflow/Definition/Design/hooks/useWorkflowGraph.ts`
- 优化 useEffect 依赖数组
- 移除不必要的 ref 依赖
- ✅ `src/pages/Workflow/Definition/Design/hooks/useWorkflowData.ts`
- 修复未使用变量警告
## 🚀 性能优化建议
### 1. 进一步优化
```typescript
// 可以考虑使用 useMemo 记忆化复杂计算
const nodeDefinitionsMap = useMemo(() => {
return nodeDefinitions.reduce((map, def) => {
map[def.nodeType] = def;
return map;
}, {} as Record<string, NodeDefinitionResponse>);
}, [nodeDefinitions]);
```
### 2. 代码分割
```typescript
// 大的组件可以进一步拆分,减少重新渲染范围
const NodePanel = React.memo(NodePanelComponent);
const WorkflowToolbar = React.memo(ToolbarComponent);
```
## 📈 修复前后对比
| 指标 | 修复前 | 修复后 |
|------|--------|--------|
| 控制台错误 | ❌ 无限循环警告 | ✅ 无错误 |
| 页面加载 | ❌ 卡死/缓慢 | ✅ 正常加载 |
| 内存使用 | ❌ 持续增长 | ✅ 稳定 |
| 用户体验 | ❌ 界面卡顿 | ✅ 流畅操作 |
## 🎉 测试结果
- [x] 无限循环错误已解决
- [x] 页面加载正常
- [x] 所有功能正常工作
- [x] 性能表现良好
修复完成!🚀

View File

@ -1,147 +0,0 @@
# 🎉 迁移完成报告
## ✅ 迁移执行状态:成功完成!
**执行时间**2025-10-20 14:33
**迁移方式**:安全备份替换法
## 📋 执行的操作
### 1. 文件迁移 ✅
```bash
# 备份原始文件
move index.tsx index.tsx.backup # 57,176 bytes → 备份
# 重构版本成为主文件
move RefactoredIndex.tsx index.tsx # 4,390 bytes → 新主文件
```
### 2. 路由清理 ✅
- 删除了测试路由配置:`:id/design-refactored`
- 移除了 `WorkflowDesignRefactored` 导入
- 保持原有路径 `:id/design` 不变
### 3. 代码验证 ✅
- 无 linter 错误
- 文件结构完整
- 依赖关系正常
## 📊 迁移效果对比
| 指标 | 迁移前 | 迁移后 | 改进 |
|------|--------|--------|------|
| **主文件大小** | 57,176 bytes | 4,390 bytes | -92.3% |
| **代码行数** | 1,541 行 | 136 行 | -91.2% |
| **文件数量** | 1 个主文件 | 13 个模块文件 | +1200% |
| **架构复杂度** | 单体巨石 | 模块化架构 | 现代化 |
## 🗂️ 重构后的文件结构
```
Design/
├── index.tsx # 主组件 (136行)
├── index.tsx.backup # 原始备份 (1541行)
├── components/ # UI 组件
│ ├── WorkflowToolbar.tsx # 工具栏
│ ├── WorkflowCanvas.tsx # 画布
│ ├── NodePanel.tsx # 节点面板
│ ├── NodeConfigModal.tsx # 节点配置
│ └── ExpressionModal.tsx # 表达式配置
├── hooks/ # 自定义 Hooks
│ ├── useWorkflowGraph.ts # 图形管理
│ ├── useWorkflowData.ts # 数据管理
│ ├── useWorkflowModals.ts # 弹窗管理
│ └── useWorkflowDragDrop.ts # 拖拽管理
├── utils/ # 工具类
│ ├── graph/ # 图形工具
│ │ ├── graphConfig.ts # X6 配置
│ │ ├── graphInitializer.ts # 初始化器
│ │ ├── eventHandlers.ts # 事件处理
│ │ └── eventRegistrar.ts # 事件注册
│ ├── nodeUtils.ts # 节点工具
│ └── validator.ts # 验证工具
├── types.ts # 类型定义
├── constants.ts # 常量定义
├── service.ts # API 服务
└── index.less # 样式文件
```
## 🚀 访问方式
**访问地址不变**
```
http://localhost:3000/workflow/definition/:id/design
```
例如:
```
http://localhost:3000/workflow/definition/3/design
```
## 🔍 功能验证清单
请验证以下功能是否正常:
### 基础功能
- [ ] 页面正常加载,无白屏
- [ ] 左侧节点面板显示正常
- [ ] 工具栏按钮显示正常
- [ ] 画布和小地图显示正常
### 核心功能
- [ ] 拖拽节点到画布
- [ ] 节点双击编辑
- [ ] 节点右键菜单
- [ ] 节点间连线
- [ ] 连线条件设置
- [ ] 保存工作流
- [ ] 撤销/重做功能
### 交互体验
- [ ] 页面响应流畅
- [ ] 无控制台错误
- [ ] 快捷键正常工作
- [ ] 拖拽交互流畅
## 🔄 回滚方案
如果发现问题需要回滚:
```bash
cd src/pages/Workflow/Definition/Design/
move index.tsx index.tsx.refactored
move index.tsx.backup index.tsx
```
## 🧹 后续清理(可选)
迁移稳定后可以清理:
```bash
# 删除备份文件
rm index.tsx.backup
# 删除迁移文档(可选)
rm MIGRATION.md MIGRATION-COMPLETE.md BUGFIX*.md TESTING.md README.md
```
## 🎊 重构成就解锁
- 🏆 **代码瘦身大师**: 代码量减少91.2%
- 🏗️ **架构重构专家**: 从单体到模块化
- 🚀 **性能优化达人**: 显著提升可维护性
- 🛠️ **现代化改造**: Hook + TypeScript 最佳实践
- 👥 **团队协作优化**: 便于多人开发维护
## 📞 技术支持
如有问题:
1. 检查控制台错误
2. 对比功能差异
3. 必要时快速回滚
---
**🎉 恭喜!你已经成功完成了从 1541 行单体代码到现代化模块架构的史诗级重构!**
**享受新的开发体验吧!** 🚀✨

View File

@ -1,161 +0,0 @@
# 🚀 工作流设计器迁移指南
## ✅ 迁移前检查清单
- [x] 重构版本功能正常
- [x] 保存功能已验证
- [x] 无限循环问题已解决
- [x] 调试代码已清理
- [x] 所有核心功能已测试
## 🎯 迁移方案选择
### 方案 1安全备份替换推荐
**适合场景**:生产环境,风险控制
**优点**:最安全,可快速回滚
```bash
# 1. 备份原始文件
mv src/pages/Workflow/Definition/Design/index.tsx src/pages/Workflow/Definition/Design/index.tsx.backup
# 2. 重命名重构版本为新的主文件
mv src/pages/Workflow/Definition/Design/RefactoredIndex.tsx src/pages/Workflow/Definition/Design/index.tsx
# 3. 测试验证无问题后,删除备份(可选)
# rm src/pages/Workflow/Definition/Design/index.tsx.backup
```
### 方案 2路由导入切换
**适合场景**:快速验证,多环境测试
**优点**:不需要重命名文件
```typescript
// 修改 src/router/index.tsx 第34行
// 原来:
const WorkflowDesign = lazy(() => import('../pages/Workflow/Definition/Design'));
// 改为:
const WorkflowDesign = lazy(() => import('../pages/Workflow/Definition/Design/RefactoredIndex'));
```
### 方案 3渐进式迁移
**适合场景**:团队协作,逐步验证
**优点**:可以长期并行存在
保持两个版本同时存在,通过不同路由访问:
- 原版:`/workflow/definition/:id/design`
- 重构版:`/workflow/definition/:id/design-refactored`
## 🚀 执行迁移推荐方案1
### 步骤 1执行文件替换
```bash
# 在项目根目录执行
cd src/pages/Workflow/Definition/Design/
# 备份原文件
mv index.tsx index.tsx.backup
# 重构版本成为新的主文件
mv RefactoredIndex.tsx index.tsx
```
### 步骤 2清理测试路由
如果不再需要测试路由,可以清理:
```typescript
// src/router/index.tsx 中删除这些行:
const WorkflowDesignRefactored = lazy(() => import('../pages/Workflow/Definition/Design/RefactoredIndex'));
// 删除这个路由配置:
{
path: ':id/design-refactored',
element: (
<Suspense fallback={<LoadingComponent/>}>
<WorkflowDesignRefactored/>
</Suspense>
)
}
```
### 步骤 3验证迁移
1. **重启开发服务器**
```bash
pnpm dev
```
2. **访问原路径验证**
```
http://localhost:3000/workflow/definition/3/design
```
3. **功能完整性测试**
- [ ] 页面正常加载
- [ ] 节点面板显示正常
- [ ] 拖拽节点功能正常
- [ ] 节点双击编辑正常
- [ ] 连线功能正常
- [ ] 工具栏所有按钮正常
- [ ] 保存功能正常
- [ ] 撤销/重做功能正常
## 🔄 回滚方案
如果发现问题需要回滚:
```bash
# 快速回滚到原版本
mv index.tsx index.tsx.refactored
mv index.tsx.backup index.tsx
# 重启开发服务器
pnpm dev
```
## 🧹 清理工作
迁移成功并稳定运行后,可以清理不需要的文件:
```bash
# 删除备份文件
rm index.tsx.backup
# 删除重构相关文档(可选)
rm README.md TESTING.md BUGFIX.md BUGFIX-V2.md MIGRATION.md
```
## 📊 迁移前后对比
| 文件 | 迁移前 | 迁移后 |
|------|--------|--------|
| **主组件** | `index.tsx` (1541行) | `index.tsx` (原RefactoredIndex.tsx, 131行) |
| **代码结构** | 单体架构 | 模块化架构 |
| **文件数量** | 1个主文件 | 13个模块文件 |
| **可维护性** | 低 | 高 |
| **功能完整性** | ✅ | ✅ |
## 🎉 迁移完成验证
迁移完成后,你应该看到:
- ✅ 所有功能正常工作
- ✅ 页面加载流畅
- ✅ 代码结构清晰
- ✅ 便于后续维护
## 📞 技术支持
如果迁移过程中遇到问题:
1. 首先尝试回滚到备份版本
2. 检查控制台错误信息
3. 对比新旧版本的差异
4. 逐步验证各个功能模块
---
**恭喜!你已经成功从 1541 行的单体代码重构为现代化的模块架构!** 🎊

View File

@ -1,105 +0,0 @@
# 工作流设计器重构说明
## 重构目标
将原本 1541 行的巨型 `index.tsx` 文件重构为模块化、可维护的组件结构。
## 重构后的目录结构
```
Design/
├── components/ # UI 组件
│ ├── WorkflowToolbar.tsx # 工具栏组件
│ ├── WorkflowCanvas.tsx # 画布组件
│ ├── NodePanel.tsx # 节点面板 (已存在)
│ ├── NodeConfigModal.tsx # 节点配置弹窗 (已存在)
│ └── ExpressionModal.tsx # 表达式弹窗 (已存在)
├── hooks/ # 自定义 Hooks
│ ├── useWorkflowGraph.ts # 图形管理
│ ├── useWorkflowData.ts # 数据管理
│ ├── useWorkflowModals.ts # 弹窗管理
│ └── useWorkflowDragDrop.ts # 拖拽管理
├── utils/ # 工具类
│ ├── graph/ # 图形相关工具
│ │ ├── graphConfig.ts # X6 配置
│ │ ├── graphInitializer.ts # 图形初始化器
│ │ ├── eventHandlers.ts # 事件处理工具类
│ │ └── eventRegistrar.ts # 事件注册器
│ ├── nodeUtils.ts # 节点工具 (已存在)
│ └── validator.ts # 验证工具 (已存在)
├── index.tsx # 原始文件 (保留)
├── RefactoredIndex.tsx # 重构后的主组件
├── types.ts # 类型定义 (已存在)
├── constants.ts # 常量 (已存在)
├── service.ts # 服务 (已存在)
└── index.less # 样式 (已存在)
```
## 重构收益
### 1. 代码可维护性提升
- **原始文件**: 1541 行,所有逻辑混在一起
- **重构后**: 拆分为 13 个独立文件,职责单一
### 2. 组件化架构
- **WorkflowToolbar**: 独立的工具栏组件,便于复用和测试
- **WorkflowCanvas**: 画布容器组件,职责明确
- **各种 Hooks**: 逻辑复用,状态管理清晰
### 3. 功能模块化
- **图形管理**: `GraphInitializer`, `EventRegistrar` 等独立类
- **事件处理**: `NodeStyleManager`, `PortManager` 等工具类
- **状态管理**: 每个 Hook 负责特定功能的状态
### 4. 类型安全
- 所有模块都有明确的 TypeScript 类型定义
- 接口清晰,便于协作开发
## 使用方式
### 切换到重构版本
```typescript
// 在路由配置中将导入更改为:
const WorkflowDesign = lazy(() => import('../pages/Workflow/Definition/Design/RefactoredIndex'));
```
### 自定义扩展
```typescript
// 扩展工具栏
<WorkflowToolbar
// ... 现有 props
customActions={<CustomButton />}
/>
// 扩展 Hook
const useCustomWorkflow = () => {
const workflow = useWorkflowGraph(/*...*/);
// 添加自定义逻辑
return { ...workflow, customMethod };
};
```
## 文件对比
| 方面 | 原始版本 | 重构版本 |
|------|----------|----------|
| 文件数量 | 1 个文件 | 13 个文件 |
| 代码行数 | 1541 行 | 分散到各模块 |
| 函数长度 | 超长函数 | 短小精悍 |
| 职责分离 | 混乱 | 清晰 |
| 可测试性 | 困难 | 容易 |
| 可维护性 | 低 | 高 |
## 技术栈
- **React 18** + **TypeScript**
- **AntV X6** - 图形编辑引擎
- **Ant Design** - UI 组件库
- **Custom Hooks** - 状态和逻辑管理
## 后续优化建议
1. **添加单元测试**: 为各个 Hook 和工具类添加测试用例
2. **性能优化**: 使用 `React.memo` 优化组件渲染
3. **国际化**: 提取所有文本到国际化文件
4. **主题定制**: 支持自定义主题配置
5. **插件系统**: 设计插件接口,支持功能扩展

View File

@ -1,152 +0,0 @@
# RefactoredIndex.tsx 测试指南
## 🚀 快速测试方法
### 方法1并行测试路由推荐
我已经为你创建了新的测试路由,你可以同时测试新旧两个版本:
**原版地址**`/workflow/definition/:id/design`
**重构版地址**`/workflow/definition/:id/design-refactored`
#### 测试步骤:
1. **启动开发服务器**
```bash
pnpm dev
```
2. **访问原版(确保正常)**
```
http://localhost:3000/workflow/definition/3/design
```
3. **访问重构版(测试新版)**
```
```
http://localhost:3000/workflow/definition/3/design-refactored
```
4. **对比测试功能**
- 左侧节点面板是否正常显示
- 拖拽节点到画布是否正常
- 节点双击编辑是否正常
- 工具栏按钮是否都能工作
- 保存功能是否正常
- 撤销/重做是否正常
### 方法2临时替换谨慎使用
如果你想直接替换现有版本进行测试:
```typescript
// 在 src/router/index.tsx 中临时修改第34行
const WorkflowDesign = lazy(() => import('../pages/Workflow/Definition/Design/RefactoredIndex'));
```
## 🧪 功能测试清单
### ✅ 基础功能测试
- [ ] 页面正常加载,无报错
- [ ] 左侧节点面板显示正常
- [ ] 工具栏按钮显示正常
- [ ] 画布和小地图显示正常
### ✅ 节点操作测试
- [ ] 从面板拖拽节点到画布
- [ ] 节点悬停效果(边框变绿,显示连接桩)
- [ ] 节点双击打开配置弹窗
- [ ] 节点右键菜单(编辑、删除)
- [ ] 节点配置保存更新
### ✅ 连线操作测试
- [ ] 节点间可以正常连线
- [ ] 连线悬停效果
- [ ] 连线右键菜单(编辑条件、删除)
- [ ] 网关节点的条件设置
### ✅ 工具栏功能测试
- [ ] 撤销/重做按钮
- [ ] 复制/剪切/粘贴
- [ ] 放大/缩小
- [ ] 全选/删除
- [ ] 保存功能
### ✅ 高级功能测试
- [ ] 键盘快捷键Ctrl+A 全选)
- [ ] 工作流保存和还原
- [ ] 小地图同步显示
- [ ] 画布拖拽和缩放
## 🐛 常见问题排查
### 1. 编译错误
```bash
# 检查 TypeScript 编译错误
pnpm build
```
### 2. 控制台错误
打开浏览器开发者工具,查看:
- Console 面板的 JavaScript 错误
- Network 面板的请求失败
- React DevTools 的组件错误
### 3. 功能对比
如果发现功能差异,对比两个版本:
- 原版:`/workflow/definition/:id/design`
- 重构版:`/workflow/definition/:id/design-refactored`
## 📊 性能测试
### 1. 加载时间对比
使用浏览器 Performance 工具测试:
- 页面首次加载时间
- 组件渲染时间
- JavaScript 执行时间
### 2. 内存使用对比
使用 Chrome DevTools Memory 面板:
- 初始内存占用
- 操作后内存变化
- 是否有内存泄漏
## 🔄 切换到生产版本
### 测试通过后,正式切换:
1. **备份原文件**
```bash
mv src/pages/Workflow/Definition/Design/index.tsx src/pages/Workflow/Definition/Design/index.tsx.backup
```
2. **替换为重构版本**
```bash
mv src/pages/Workflow/Definition/Design/RefactoredIndex.tsx src/pages/Workflow/Definition/Design/index.tsx
```
3. **或直接修改路由导入**
```typescript
// 将 src/router/index.tsx 第34行改为
const WorkflowDesign = lazy(() => import('../pages/Workflow/Definition/Design/RefactoredIndex'));
```
## 📝 测试反馈
如果在测试过程中发现问题,请记录:
1. **错误信息**:完整的控制台错误日志
2. **重现步骤**:详细的操作步骤
3. **预期行为**:应该发生什么
4. **实际行为**:实际发生了什么
5. **环境信息**:浏览器版本、操作系统等
## 🎯 测试建议
1. **先在开发环境测试**,确保没有明显问题
2. **使用真实的工作流数据**进行测试
3. **测试各种边界情况**(大量节点、复杂连线等)
4. **多浏览器测试**Chrome、Firefox、Safari
5. **不同屏幕尺寸测试**(桌面、平板)
祝测试顺利!🎉

View File

@ -1,7 +1,7 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import {Tabs, TabsProps} from 'antd'; import {Tabs, TabsProps} from 'antd';
import {Cell} from '@antv/x6'; import {Cell} from '@antv/x6';
import type {NodeDefinitionResponse} from "@/workflow/nodes/nodeService"; import type {NodeDefinitionResponse} from "../nodes/nodeService";
import { import {
Sheet, Sheet,
SheetContent, SheetContent,

View File

@ -12,8 +12,8 @@ import {
AppstoreOutlined, AppstoreOutlined,
BranchesOutlined BranchesOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import {getNodeDefinitionList} from "../service"; import {getNodeDefinitionList} from "../nodes/nodeService";
import type {NodeDefinitionResponse} from "@/workflow/nodes/nodeService"; import type {NodeDefinitionResponse} from "../nodes/nodeService";
// 使用 Collapse 组件,不需要解构 Panel // 使用 Collapse 组件,不需要解构 Panel

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import NodePanel from './NodePanel'; import NodePanel from './NodePanel';
import type { NodeDefinitionResponse } from "@/workflow/nodes/nodeService"; import type { NodeDefinitionResponse } from "../nodes/nodeService";
interface WorkflowCanvasProps { interface WorkflowCanvasProps {
graphContainerRef: React.RefObject<HTMLDivElement>; graphContainerRef: React.RefObject<HTMLDivElement>;

View File

@ -2,10 +2,10 @@ import { useState, useEffect, useCallback } from 'react';
import { message } from 'antd'; import { message } from 'antd';
import { Graph } from '@antv/x6'; import { Graph } from '@antv/x6';
import { getDefinitionDetail, saveDefinition } from '../../Definition/service'; import { getDefinitionDetail, saveDefinition } from '../../Definition/service';
import { getNodeDefinitionList } from '../service'; import { getNodeDefinitionList } from '../nodes/nodeService';
import { validateWorkflow } from '../utils/validator'; import { validateWorkflow } from '../utils/validator';
import { addNodeToGraph } from '../utils/nodeUtils'; import { addNodeToGraph } from '../utils/nodeUtils';
import type { NodeDefinitionResponse } from '@/workflow/nodes/nodeService'; import type { NodeDefinitionResponse } from '../nodes/nodeService';
/** /**
* Hook * Hook

View File

@ -1,7 +1,7 @@
import { Graph } from '@antv/x6'; import { Graph } from '@antv/x6';
import { message } from 'antd'; import { message } from 'antd';
import { addNodeToGraph } from '../utils/nodeUtils'; import { addNodeToGraph } from '../utils/nodeUtils';
import type { NodeDefinitionResponse } from '@/workflow/nodes/nodeService'; import type { NodeDefinitionResponse } from '../nodes/nodeService';
/** /**
* Hook * Hook

View File

@ -3,7 +3,7 @@ import { Graph, Edge } from '@antv/x6';
import { message } from 'antd'; import { message } from 'antd';
import { GraphInitializer } from '../utils/graph/graphInitializer'; import { GraphInitializer } from '../utils/graph/graphInitializer';
import { EventRegistrar } from '../utils/graph/eventRegistrar'; import { EventRegistrar } from '../utils/graph/eventRegistrar';
import type { NodeDefinitionResponse } from '@/workflow/nodes/nodeService'; import type { NodeDefinitionResponse } from '../nodes/nodeService';
/** /**
* Hook * Hook

View File

@ -1,7 +1,7 @@
import { useState, useCallback } from 'react'; import { useState, useCallback } from 'react';
import { Cell, Edge } from '@antv/x6'; import { Cell, Edge } from '@antv/x6';
import { message } from 'antd'; import { message } from 'antd';
import type { NodeDefinitionResponse } from '@/workflow/nodes/nodeService'; import type { NodeDefinitionResponse } from '../nodes/nodeService';
import type { EdgeCondition } from '../types'; import type { EdgeCondition } from '../types';
/** /**

View File

@ -1,7 +0,0 @@
// 工作流设计器相关服务
// 使用新的节点定义系统不再依赖后端API
import { getNodeDefinitionList } from '@/workflow/nodes/nodeService';
// 导出节点定义获取函数
export { getNodeDefinitionList };

View File

@ -3,7 +3,7 @@ import { message, Modal } from 'antd';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import { Dropdown } from 'antd'; import { Dropdown } from 'antd';
import React from 'react'; import React from 'react';
import type { NodeDefinitionResponse } from "@/workflow/nodes/nodeService"; import type { NodeDefinitionResponse } from "../../nodes/nodeService";
/** /**
* *

View File

@ -1,5 +1,5 @@
import { Graph, Edge } from '@antv/x6'; import { Graph, Edge } from '@antv/x6';
import type { NodeDefinitionResponse } from "@/workflow/nodes/nodeService"; import type { NodeDefinitionResponse } from "../../nodes/nodeService";
import { NodeStyleManager, PortManager, ContextMenuManager, EdgeStyleManager, SelectionManager } from './eventHandlers'; import { NodeStyleManager, PortManager, ContextMenuManager, EdgeStyleManager, SelectionManager } from './eventHandlers';
/** /**