新编辑器与聊天面板集成方案.md 13 KB

新编辑器与聊天面板集成方案

1. 现有应用架构

1.1 双面板布局

当前应用采用ResizableLayout双面板布局:

┌─────────────────────────────────────────────────────────┐
│                      Toolbar (顶部)                      │
│              [会话历史] [文档列表]                        │
├──────────────────────┬──────────────────────────────────┤
│  Chat Panel          │  右侧面板(动态切换):              │
│  (左侧 40%)          │  - ExportRecordList (默认)       │
│  - 消息列表          │  - EditorPanel (编辑文档时)      │
│  - 输入框            │  (右侧 60%)                      │
│  - 发送按钮          │                                  │
└──────────────────────┴──────────────────────────────────┘

1.2 当前编辑流程

用户在Chat中点击"预览"按钮
        ↓
MessageItem触发 onPreviewDocument(documentId)
        ↓
uiStore.openDocumentPreview(documentId, name)
        ↓
App.tsx检测到 previewDocumentId 变化
        ↓
右侧面板从ExportRecordList切换到EditorPanel
        ↓
EditorPanel加载文档并显示WYSIWYGEditor(MDXEditor)

1.3 关键组件

组件 路径 职责
App.tsx src/App.tsx 根组件,布局编排
ChatPanel src/components/ChatPanel/ChatPanel.tsx 聊天面板(左侧)
EditorPanel src/components/EditorPanel/EditorPanel.tsx 编辑器面板(右侧)
WYSIWYGEditor src/components/EditorPanel/WYSIWYGEditor.tsx MDXEditor编辑器(旧)
uiStore src/stores/uiStore.ts UI状态管理(预览文档ID等)
chatStore src/stores/chatStore.ts 聊天消息管理

2. 新编辑器集成策略

2.1 集成原则

  • 保留聊天面板: 左侧ChatPanel完全不变
  • 保留双面板布局: ResizableLayout结构不变
  • 完全重写EditorPanel: 删除旧的WYSIWYGEditor,直接集成BlockEditor
  • 保持接口兼容: documentId传递、打开/关闭逻辑保持一致

2.2 架构对比

当前架构:

App.tsx
├── ChatPanel (左)
└── EditorPanel (右)
    └── WYSIWYGEditor (MDXEditor) ❌ 删除
        └── markdown编辑

新架构:

App.tsx
├── ChatPanel (左) ✅ 不变
└── EditorPanel (右) ⭐ 完全重写
    └── BlockEditor (新) ⭐ 直接集成
        └── blocks编辑

3. 具体集成步骤

3.1 阶段1: 创建BlockEditor(在新分支开发)

开发策略: 在新Git分支开发,避免影响主分支

git checkout -b feature/new-block-editor

src/components/Editor/目录创建新编辑器:

src/components/
├── Editor/                      # ⭐ 新目录
│   ├── BlockEditor.tsx          # 主编辑器
│   ├── BlockCanvas.tsx
│   ├── BlockRenderer.tsx
│   ├── blocks/
│   │   ├── HeadingBlock.tsx
│   │   ├── ParagraphBlock.tsx
│   │   ├── TableBlock.tsx
│   │   └── ImageBlock.tsx
│   └── toolbar/
│       ├── MainToolbar.tsx
│       └── FloatingToolbar.tsx
└── EditorPanel/                 # 现有目录(暂不动)
    ├── EditorPanel.tsx          # 旧外壳组件
    └── WYSIWYGEditor.tsx        # 旧编辑器

验收: 新编辑器在独立分支可运行,主分支功能不受影响

3.2 阶段2: 完全重写EditorPanel

删除旧文件,创建新的EditorPanel:

# 1. 备份旧文件(以防需要回滚)
git mv src/components/EditorPanel src/components/EditorPanel.backup

# 2. 创建新EditorPanel目录
mkdir src/components/EditorPanel

# 3. 创建新的EditorPanel.tsx

新的EditorPanel.tsx:

// src/components/EditorPanel/EditorPanel.tsx
import React from 'react';
import { BlockEditor } from '../Editor/BlockEditor';
import './EditorPanel.css';

interface EditorPanelProps {
  documentId: string;
  initialDocumentName?: string;
  onClose?: () => void;
}

/**
 * EditorPanel - 文档编辑面板
 * 
 * 作为右侧面板组件,直接集成BlockEditor
 * Props接口保持与旧版本兼容,确保App.tsx无需修改
 */
export const EditorPanel: React.FC<EditorPanelProps> = ({
  documentId,
  initialDocumentName,
  onClose
}) => {
  return (
    <div className="editor-panel">
      <BlockEditor 
        documentId={documentId}
        onClose={onClose}
      />
    </div>
  );
};

export default EditorPanel;

新的EditorPanel.css:

/* src/components/EditorPanel/EditorPanel.css */
.editor-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  background-color: #ffffff;
  overflow: hidden;
}

验收:

  • EditorPanel接口保持不变(Props兼容)
  • 直接显示BlockEditor
  • App.tsx无需修改
  • 聊天面板和布局完全不受影响

3.3 阶段3: 合并到主分支并部署

合并前准备:

# 1. 在feature分支完成开发和测试
npm run test
npm run build

# 2. 确保所有测试通过
npm run test:integration

# 3. 合并到主分支
git checkout main
git merge feature/new-block-editor

# 4. 删除旧的EditorPanel备份(确认无问题后)
rm -rf src/components/EditorPanel.backup

部署验证:

  1. 部署到测试环境
  2. 验证聊天功能正常
  3. 验证编辑功能正常
  4. 验证布局和拖拽正常

验收:

  • 新EditorPanel正常工作
  • 聊天面板功能完整
  • 无遗留旧代码

3.4 阶段4: 数据兼容性(如需要)

如果后端同时存在新旧文档,在editorStore中添加兼容逻辑:

// src/stores/editorStore.ts
export const useEditorStore = create<EditorStore>((set, get) => ({
  loadDocument: async (id: string) => {
    try {
      // 优先尝试加载blocks数据
      const blocks = await blockService.getBlocks(id);
      set({ blocks, documentId: id });
    } catch (error) {
      // 如果没有blocks数据,提示用户
      Modal.info({
        title: '文档格式提示',
        content: '此文档使用旧格式,暂不支持编辑。请联系管理员升级文档。'
      });
      throw error;
    }
  }
}));

验收:

  • 新文档正常加载和编辑
  • 旧文档友好提示(如果存在)

4. 保持不变的部分

4.1 聊天面板完全不变

ChatPanel组件及其子组件完全不受影响:

  • ChatPanel/ChatPanel.tsx
  • ChatPanel/MessageList.tsx
  • ChatPanel/MessageItem.tsx
  • ChatPanel/MessageInput.tsx
  • chatStore.ts

4.2 布局结构不变

  • ResizableLayout组件
  • ✅ 左侧40% / 右侧60%默认比例
  • ✅ 拖拽调整分隔线
  • ✅ 最小宽度300px限制

4.3 UI交互流程不变

用户在Chat中点击"预览"
        ↓
MessageItem.tsx: onPreviewDocument(documentId) ✅ 不变
        ↓
uiStore.openDocumentPreview(documentId) ✅ 不变
        ↓
App.tsx: previewDocumentId更新,切换右侧面板 ✅ 不变
        ↓
EditorPanel加载并显示 ✅ 外壳不变,内部替换编辑器

4.4 Store结构不变

  • uiStore: 继续管理previewDocumentIdpreviewDocumentName
  • chatStore: 继续管理消息列表
  • 新增 editorStore: 管理blocks数据

5. EditorPanel接口保持兼容

5.1 Props接口不变

interface EditorPanelProps {
  documentId: string;              // ✅ 保持
  initialDocumentName?: string;    // ✅ 保持
  onClose?: () => void;            // ✅ 保持
}

5.2 关闭逻辑不变

// App.tsx
const handleCloseEditor = useCallback(() => {
  closeDocumentPreview();  // ✅ uiStore方法保持不变
}, [closeDocumentPreview]);

// 传递给EditorPanel
<EditorPanel onClose={handleCloseEditor} />

5.3 打开逻辑不变

// MessageItem.tsx
const handlePreviewClick = () => {
  onPreviewDocument(message.documentId, message.documentName);
  // ✅ 接口保持不变
};

6. 测试计划

6.1 集成测试清单

  • 左侧ChatPanel正常显示消息
  • 点击"预览"按钮打开右侧EditorPanel
  • BlockEditor正确加载blocks数据
  • 编辑操作不影响左侧聊天
  • 关闭编辑器返回ExportRecordList
  • ResizableLayout拖拽正常
  • 切换环境变量后编辑器正确切换

6.2 回归测试清单

  • 发送消息功能正常
  • 消息滚动和自动定位正常
  • 导出记录列表显示正常
  • 文档列表drawer打开关闭正常
  • 会话历史drawer打开关闭正常
  • 离线状态提示正常

7. 代码变更清单

7.1 新增文件

src/
├── components/
│   └── Editor/                   # 新目录
│       ├── BlockEditor.tsx
│       ├── BlockCanvas.tsx
│       ├── BlockRenderer.tsx
│       ├── blocks/*.tsx
│       └── toolbar/*.tsx
├── stores/
│   └── editorStore.ts            # 新Store
├── services/
│   └── blockService.ts           # 新Service
├── types/
│   └── editor.ts                 # 新类型定义
└── utils/
    ├── blockOperations.ts
    ├── richTextConverter.ts
    └── styleResolver.ts

7.2 重写文件

src/components/EditorPanel/
├── EditorPanel.tsx               # ⭐ 完全重写(删除旧代码)
└── EditorPanel.css               # ⭐ 新增样式文件

删除文件:

src/components/EditorPanel/
├── WYSIWYGEditor.tsx             # ❌ 删除
├── WYSIWYGEditor.css             # ❌ 删除
└── 其他MDXEditor相关文件          # ❌ 删除

7.3 保持不变的文件

src/
├── App.tsx                        # ✅ 不变
├── components/
│   ├── ChatPanel/                # ✅ 完全不变
│   │   ├── ChatPanel.tsx
│   │   ├── MessageList.tsx
│   │   ├── MessageItem.tsx
│   │   └── MessageInput.tsx
│   ├── Layout/
│   │   └── ResizableLayout.tsx   # ✅ 不变
│   └── ExportRecordList/         # ✅ 不变
├── stores/
│   ├── uiStore.ts                # ✅ 不变
│   └── chatStore.ts              # ✅ 不变
└── services/
    └── documentService.ts        # ✅ 不变(或小幅扩展)

8. 风险控制

8.1 回滚方案

如果新编辑器出现严重问题:

由于已完全删除旧编辑器,回滚需要恢复代码:

# 方案1: 从Git历史恢复
git revert <merge-commit-hash>

# 方案2: 从备份恢复
git checkout <pre-merge-commit> -- src/components/EditorPanel

# 方案3: 紧急降级(如果有保留备份)
mv src/components/EditorPanel.backup src/components/EditorPanel

建议: 在确认新编辑器稳定运行1-2周后,再删除.backup目录

8.2 数据安全

  • 新编辑器只操作document_blocks
  • 后端应确保所有文档都已转换为blocks格式
  • 如果有旧文档,后端提供一次性批量迁移脚本

8.3 性能监控

集成后监控指标:

  • 右侧面板切换速度(<500ms)
  • BlockEditor加载时间(<2s)
  • 左侧聊天消息渲染不受影响
  • 布局调整响应及时

9. 开发顺序建议

Week 1-6: 独立开发BlockEditor(feature分支)

  • 创建feature/new-block-editor分支
  • src/components/Editor/创建新组件
  • 独立开发和测试,不影响主分支

Week 7: 重写EditorPanel并集成

  • 备份旧EditorPanel
  • 创建新的EditorPanel.tsx(极简外壳)
  • 直接集成BlockEditor
  • 本地完整测试

Week 8: 合并和部署测试环境

  • 合并到main分支
  • 部署到测试环境
  • 完整集成测试
  • 团队内部试用

Week 9: 生产环境部署

  • 部署到生产环境
  • 监控错误和性能
  • 收集用户反馈

Week 10: 清理和优化

  • 确认稳定后删除备份文件
  • 删除MDXEditor相关依赖
  • 更新package.json
  • 性能优化

10. FAQ

Q1: 新编辑器会影响聊天功能吗?

A: 不会。聊天面板(ChatPanel)完全独立,新编辑器只替换右侧EditorPanel内部的编辑器内核。

Q2: 旧的WYSIWYGEditor完全删除了吗?

A: 是的,EditorPanel完全重写,旧编辑器代码会被删除。但建议先备份(git mv)保留1-2周,确认无问题后再删除。

Q3: 旧的markdown文档怎么办?

A: 后端应在部署新编辑器前,将所有文档批量转换为blocks格式。前端不再处理markdown数据。

Q4: ResizableLayout需要修改吗?

A: 不需要。布局组件完全不变,只是右侧面板内部的编辑器换了。

Q5: 如何确保不破坏现有功能?

A:

  • 保持所有接口不变(Props、Store方法)
  • 通过feature flag隔离新旧代码
  • 完整的回归测试清单

文档版本: v1.0
创建日期: 2026-07-03
状态: 集成方案确认