Files
leaudit-platform-frontend/docs/monaco-editor-使用指南.md
2025-12-05 00:09:32 +08:00

6.8 KiB
Raw Permalink Blame History

Monaco Editor 差异对比功能使用指南

📦 安装依赖

在项目根目录执行以下命令安装 Monaco Editor

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 主要配置项

<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. 获取差异信息

const handleEditorDidMount = (editor: editor.IStandaloneDiffEditor) => {
  // 获取所有差异
  const lineChanges = editor.getLineChanges();
  console.log('差异数量:', lineChanges?.length);
  console.log('差异详情:', lineChanges);
};

2. 跳转到指定差异

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. 切换显示模式

// 切换为内联模式
<DiffEditor
  options={{
    renderSideBySide: false  // 内联模式,上下显示
  }}
/>

📊 实际应用场景

适用场景

  1. 合同对比:版本管理、条款变更追踪
  2. 代码审查:代码变更对比
  3. 文档版本控制:历史版本对比
  4. 配置文件对比JSON、YAML 配置变更

⚠️ 限制

  • 只能对比纯文本
  • 不支持直接对比 PDF、Word 等格式化文档
  • 需要先提取文本内容

🔄 扩展:文件上传功能

未来可以添加的功能

  1. 上传 PDF 文件 → 提取文本 → 对比
  2. 上传 Word 文件 → 提取文本 → 对比
  3. 导出差异报告 → PDF/Word 格式
  4. 保存对比结果 → 数据库存储

文本提取示例

// 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

核心代码片段

// 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

const text = await file.text(); // 自动识别编码

Q3: 如何自定义主题?

A: 使用 defineTheme 自定义:

import { editor } from 'monaco-editor';

editor.defineTheme('myCustomTheme', {
  base: 'vs',
  inherit: true,
  rules: [{ background: 'EDF9FA' }],
  colors: {
    'editor.foreground': '#000000',
    'editor.background': '#EDF9FA',
    // ... 更多颜色配置
  }
});

📚 参考资料

🚧 后续开发计划

  • 添加文件上传功能
  • 支持 PDF 文本提取
  • 支持 Word 文本提取
  • 添加差异统计图表
  • 导出对比报告(PDF/Word
  • 保存对比历史记录
  • 支持多人协同对比

作者: 中国烟草AI合同及卷宗审核系统开发团队 更新时间: 2025-01-24