all in
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
# Monaco Editor 差异对比功能使用指南
|
||||
|
||||
## 📦 安装依赖
|
||||
|
||||
在项目根目录执行以下命令安装 Monaco Editor:
|
||||
|
||||
```bash
|
||||
npm install monaco-editor @monaco-editor/react
|
||||
```
|
||||
|
||||
### 依赖说明
|
||||
|
||||
- **monaco-editor**: Monaco Editor 核心包(VS Code 的编辑器组件)
|
||||
- **@monaco-editor/react**: Monaco Editor 的 React 封装,提供 React 组件
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 访问演示页面
|
||||
|
||||
启动项目后,访问:`http://localhost:5173/monaco-demo`
|
||||
|
||||
### 2. 查看效果
|
||||
|
||||
页面会展示两份合同的差异对比:
|
||||
- **左侧**:原始合同(2024年1月版本)
|
||||
- **右侧**:修改后的合同(2024年3月版本)
|
||||
|
||||
### 3. 使用导航功能
|
||||
|
||||
- **上一处差异**:跳转到前一个修改位置
|
||||
- **下一处差异**:跳转到后一个修改位置
|
||||
- **重置示例**:恢复默认的示例文本
|
||||
|
||||
## 🎨 差异高亮说明
|
||||
|
||||
| 颜色 | 含义 | 示例 |
|
||||
|------|------|------|
|
||||
| 🟢 **绿色** | 新增的行 | `+ 第七条 保密条款(新增)` |
|
||||
| 🔴 **红色** | 删除的行 | `- 第八条 其他约定` |
|
||||
| 🟡 **黄色** | 修改的内容 | `总金额:1,000,000 → 1,500,000` |
|
||||
|
||||
## 📂 文件结构
|
||||
|
||||
```
|
||||
app/
|
||||
├── routes/
|
||||
│ └── monaco-demo.tsx # Monaco 演示页面
|
||||
└── docs/
|
||||
└── monaco-editor-使用指南.md # 本文档
|
||||
```
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
### DiffEditor 主要配置项
|
||||
|
||||
```typescript
|
||||
<DiffEditor
|
||||
height="100%" // 编辑器高度
|
||||
language="plaintext" // 语言模式(plaintext/javascript/json等)
|
||||
original={originalText} // 原始文本
|
||||
modified={modifiedText} // 修改后的文本
|
||||
options={{
|
||||
readOnly: true, // 只读模式
|
||||
renderSideBySide: true, // 并排显示(false为内联模式)
|
||||
ignoreTrimWhitespace: false, // 不忽略空格差异
|
||||
fontSize: 14, // 字体大小
|
||||
wordWrap: 'on', // 自动换行
|
||||
minimap: { enabled: true }, // 显示缩略图
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
### 常用选项
|
||||
|
||||
| 选项 | 说明 | 可选值 |
|
||||
|------|------|--------|
|
||||
| `readOnly` | 是否只读 | `true` / `false` |
|
||||
| `renderSideBySide` | 并排/内联显示 | `true`(并排) / `false`(内联) |
|
||||
| `ignoreTrimWhitespace` | 忽略首尾空格 | `true` / `false` |
|
||||
| `fontSize` | 字体大小 | 数字,如 `14` |
|
||||
| `wordWrap` | 自动换行 | `'on'` / `'off'` / `'wordWrapColumn'` |
|
||||
| `theme` | 主题 | `'vs'`(浅色) / `'vs-dark'`(深色) / `'hc-black'`(高对比度) |
|
||||
|
||||
## 🔧 高级功能
|
||||
|
||||
### 1. 获取差异信息
|
||||
|
||||
```typescript
|
||||
const handleEditorDidMount = (editor: editor.IStandaloneDiffEditor) => {
|
||||
// 获取所有差异
|
||||
const lineChanges = editor.getLineChanges();
|
||||
console.log('差异数量:', lineChanges?.length);
|
||||
console.log('差异详情:', lineChanges);
|
||||
};
|
||||
```
|
||||
|
||||
### 2. 跳转到指定差异
|
||||
|
||||
```typescript
|
||||
const goToDiff = (index: number) => {
|
||||
const lineChanges = diffEditorRef.current?.getLineChanges();
|
||||
if (!lineChanges || index >= lineChanges.length) return;
|
||||
|
||||
const change = lineChanges[index];
|
||||
const modifiedEditor = diffEditorRef.current.getModifiedEditor();
|
||||
|
||||
// 跳转并高亮
|
||||
modifiedEditor.revealLineInCenter(change.modifiedStartLineNumber);
|
||||
modifiedEditor.setPosition({
|
||||
lineNumber: change.modifiedStartLineNumber,
|
||||
column: 1
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
### 3. 切换显示模式
|
||||
|
||||
```typescript
|
||||
// 切换为内联模式
|
||||
<DiffEditor
|
||||
options={{
|
||||
renderSideBySide: false // 内联模式,上下显示
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## 📊 实际应用场景
|
||||
|
||||
### ✅ 适用场景
|
||||
|
||||
1. **合同对比**:版本管理、条款变更追踪
|
||||
2. **代码审查**:代码变更对比
|
||||
3. **文档版本控制**:历史版本对比
|
||||
4. **配置文件对比**:JSON、YAML 配置变更
|
||||
|
||||
### ⚠️ 限制
|
||||
|
||||
- 只能对比**纯文本**
|
||||
- 不支持直接对比 PDF、Word 等格式化文档
|
||||
- 需要先提取文本内容
|
||||
|
||||
## 🔄 扩展:文件上传功能
|
||||
|
||||
### 未来可以添加的功能
|
||||
|
||||
1. **上传 PDF 文件** → 提取文本 → 对比
|
||||
2. **上传 Word 文件** → 提取文本 → 对比
|
||||
3. **导出差异报告** → PDF/Word 格式
|
||||
4. **保存对比结果** → 数据库存储
|
||||
|
||||
### 文本提取示例
|
||||
|
||||
```typescript
|
||||
// PDF 文本提取(需要 pdf-parse 或 pdfjs)
|
||||
import * as pdfjsLib from 'pdfjs-dist';
|
||||
|
||||
async function extractPdfText(file: File): Promise<string> {
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const pdf = await pdfjsLib.getDocument(arrayBuffer).promise;
|
||||
|
||||
let text = '';
|
||||
for (let i = 1; i <= pdf.numPages; i++) {
|
||||
const page = await pdf.getPage(i);
|
||||
const content = await page.getTextContent();
|
||||
text += content.items.map(item => item.str).join(' ') + '\n';
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
// Word 文本提取(需要 mammoth)
|
||||
import mammoth from 'mammoth';
|
||||
|
||||
async function extractWordText(file: File): Promise<string> {
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const result = await mammoth.extractRawText({ arrayBuffer });
|
||||
return result.value;
|
||||
}
|
||||
```
|
||||
|
||||
## 📝 示例代码位置
|
||||
|
||||
完整代码请查看:`app/routes/monaco-demo.tsx`
|
||||
|
||||
### 核心代码片段
|
||||
|
||||
```typescript
|
||||
// 1. 引入组件
|
||||
import { DiffEditor } from "@monaco-editor/react";
|
||||
|
||||
// 2. 定义文本
|
||||
const originalText = "原始合同内容...";
|
||||
const modifiedText = "修改后的合同内容...";
|
||||
|
||||
// 3. 渲染 Diff Editor
|
||||
<DiffEditor
|
||||
height="90vh"
|
||||
language="plaintext"
|
||||
original={originalText}
|
||||
modified={modifiedText}
|
||||
options={{
|
||||
readOnly: true,
|
||||
renderSideBySide: true,
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## 🎯 性能优化建议
|
||||
|
||||
1. **大文件处理**:文本超过 10MB 时,考虑分段加载
|
||||
2. **虚拟滚动**:Monaco 自带虚拟滚动,支持大文件
|
||||
3. **懒加载**:使用 React.lazy 懒加载 Monaco 组件
|
||||
4. **Web Worker**:文本提取放在 Worker 中处理
|
||||
|
||||
## 🐛 常见问题
|
||||
|
||||
### Q1: Monaco Editor 加载慢?
|
||||
|
||||
**A**: Monaco Editor 体积较大(~5MB),建议:
|
||||
- 使用 CDN 加速
|
||||
- 开启 gzip 压缩
|
||||
- 使用代码分割
|
||||
|
||||
### Q2: 中文显示乱码?
|
||||
|
||||
**A**: 确保文件编码为 UTF-8:
|
||||
```typescript
|
||||
const text = await file.text(); // 自动识别编码
|
||||
```
|
||||
|
||||
### Q3: 如何自定义主题?
|
||||
|
||||
**A**: 使用 `defineTheme` 自定义:
|
||||
```typescript
|
||||
import { editor } from 'monaco-editor';
|
||||
|
||||
editor.defineTheme('myCustomTheme', {
|
||||
base: 'vs',
|
||||
inherit: true,
|
||||
rules: [{ background: 'EDF9FA' }],
|
||||
colors: {
|
||||
'editor.foreground': '#000000',
|
||||
'editor.background': '#EDF9FA',
|
||||
// ... 更多颜色配置
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 📚 参考资料
|
||||
|
||||
- [Monaco Editor 官方文档](https://microsoft.github.io/monaco-editor/)
|
||||
- [@monaco-editor/react 文档](https://github.com/suren-atoyan/monaco-react)
|
||||
- [VS Code API 文档](https://code.visualstudio.com/api)
|
||||
|
||||
## 🚧 后续开发计划
|
||||
|
||||
- [ ] 添加文件上传功能
|
||||
- [ ] 支持 PDF 文本提取
|
||||
- [ ] 支持 Word 文本提取
|
||||
- [ ] 添加差异统计图表
|
||||
- [ ] 导出对比报告(PDF/Word)
|
||||
- [ ] 保存对比历史记录
|
||||
- [ ] 支持多人协同对比
|
||||
|
||||
---
|
||||
|
||||
**作者**: 中国烟草AI合同及卷宗审核系统开发团队
|
||||
**更新时间**: 2025-01-24
|
||||
Reference in New Issue
Block a user