From 60649412654f14dfe63153c95210fe1b656a206c Mon Sep 17 00:00:00 2001 From: yorn <1057707203@qq.com> Date: Tue, 25 Nov 2025 15:04:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=90=88=E5=90=8C=E6=AF=94?= =?UTF-8?q?=E5=AF=B9demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/routes/monaco-demo.tsx | 126 ++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 57 deletions(-) diff --git a/app/routes/monaco-demo.tsx b/app/routes/monaco-demo.tsx index b3228cc..7bb8f33 100644 --- a/app/routes/monaco-demo.tsx +++ b/app/routes/monaco-demo.tsx @@ -134,6 +134,11 @@ export default function MonacoDemoPage() { const [currentDiff, setCurrentDiff] = useState(0); // 文档相关状态 + // 默认使用的测试文档路径(相对路径) + // 注意:文件名中使用的是中文全角括号()而不是英文半角括号() + const DEFAULT_DOC1_URL = '/testWork/(最终版)智慧法务平台建设采购项目合同(1).docx'; + const DEFAULT_DOC2_URL = '/testWork/(最终版)智慧法务平台建设采购项目合同(2).docx'; + const [doc1Url, setDoc1Url] = useState(''); const [doc2Url, setDoc2Url] = useState(''); const [doc1Info, setDoc1Info] = useState(null); @@ -222,9 +227,9 @@ export default function MonacoDemoPage() { const arrayBuffer = await response.arrayBuffer(); // 使用 mammoth 提取纯文本 - const result = await mammoth.extractRawText({ arrayBuffer }); + const textResult = await mammoth.extractRawText({ arrayBuffer }); - return result.value; + return textResult.value; }; // 加载文档并提取文本(支持 PDF 和 Word) @@ -276,6 +281,7 @@ export default function MonacoDemoPage() { setDocInfo(docInfo); setTextContent(text); + toastService.success(`Word文档加载成功!提取了 ${text.length} 个字符`); } else { toastService.error('不支持的文件类型'); @@ -365,45 +371,33 @@ export default function MonacoDemoPage() { }, 100); }; - // 构建文件访问 URL - const buildFileUrl = (filePath: string): string => { - // 如果路径以 public/ 开头或者以已知的 public 子目录开头(如 testWork/) - // 则直接使用静态资源路径 - if (filePath.startsWith('public/')) { - // 去掉 public/ 前缀,直接访问静态资源 - return '/' + filePath.substring(7); - } else if (filePath.startsWith('testWork/') || filePath.startsWith('testPDF/')) { - // testWork 和 testPDF 目录在 public 下,直接作为静态资源访问 - return '/' + filePath; - } else { - // 其他路径通过 api/pdf-proxy 代理访问(从 MinIO 获取) - return `/api/pdf-proxy?path=${encodeURIComponent(filePath)}`; - } - }; - // 从URL参数加载文档(支持 PDF 和 Word) const loadDocumentsFromUrl = () => { if (typeof window === 'undefined') return; const searchParams = new URLSearchParams(window.location.search); - const doc1Path = searchParams.get('doc1') || searchParams.get('pdf1'); // 兼容旧参数名 - const doc2Path = searchParams.get('doc2') || searchParams.get('pdf2'); // 兼容旧参数名 + const doc1Param = searchParams.get('doc1') || searchParams.get('pdf1'); // 兼容旧参数名 + const doc2Param = searchParams.get('doc2') || searchParams.get('pdf2'); // 兼容旧参数名 - if (doc1Path || doc2Path) { + // 只有在传参时才加载文档,否则使用默认的 mock 数据(示例合同) + if (doc1Param || doc2Param) { setUseExample(false); - if (doc1Path) { - const fullUrl = buildFileUrl(doc1Path); - setDoc1Url(fullUrl); - loadDocumentAndExtractText(fullUrl, doc1Path, setDoc1Info, setIsLoadingDoc1, setOriginalText); + // 文档1 + if (doc1Param) { + const doc1Url = doc1Param.startsWith('/') ? doc1Param : '/' + doc1Param; // 相对路径,确保以 / 开头 + setDoc1Url(doc1Url); + loadDocumentAndExtractText(doc1Url, doc1Param, setDoc1Info, setIsLoadingDoc1, setOriginalText); } - if (doc2Path) { - const fullUrl = buildFileUrl(doc2Path); - setDoc2Url(fullUrl); - loadDocumentAndExtractText(fullUrl, doc2Path, setDoc2Info, setIsLoadingDoc2, setModifiedText); + // 文档2 + if (doc2Param) { + const doc2Url = doc2Param.startsWith('/') ? doc2Param : '/' + doc2Param; // 相对路径,确保以 / 开头 + setDoc2Url(doc2Url); + loadDocumentAndExtractText(doc2Url, doc2Param, setDoc2Info, setIsLoadingDoc2, setModifiedText); } } + // 如果没有传参,则保持 useExample=true,显示默认的 CONTRACT_A 和 CONTRACT_B }; // 组件挂载时读取URL参数 @@ -412,8 +406,46 @@ export default function MonacoDemoPage() { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + // 监听文本变化,重新计算差异数量 + useEffect(() => { + // 延迟一点确保编辑器已经渲染完成 + const timer = setTimeout(() => { + if (diffEditorRef.current) { + const lineChanges = diffEditorRef.current.getLineChanges(); + if (lineChanges) { + setDiffCount(lineChanges.length); + console.log(`✅ 重新计算差异: 发现 ${lineChanges.length} 处差异`); + } + } + }, 100); + + return () => clearTimeout(timer); + }, [originalText, modifiedText]); // 当文本内容变化时重新计算 + return (
+ {/* 字符级差异高亮样式 - 加深高亮颜色 */} + + {/* 页面头部 */}
重置示例 - - {/* 未来扩展:上传按钮 */} -
{/* 文档加载信息 */} - {!useExample && (doc1Info || doc2Info || isLoadingDoc1 || isLoadingDoc2) && ( + {!useExample && (doc1Info || doc2Info || isLoadingDoc1 || isLoadingDoc2) && 2==1 && (
差异高亮说明:
    -
  • 绿色:新增的内容
  • -
  • 红色:删除的内容
  • -
  • 黄色背景:修改的行内差异
  • +
  • 左侧红色背景:原始版本的内容(在新版本中被删除或修改前的内容)
  • +
  • 右侧绿色背景:修改版本的内容(新增或修改后的内容)
  • +
  • 深色高亮:行内具体修改的字符差异
{useExample && (
💡 使用提示:
- 您可以通过URL参数加载文档进行对比(支持 PDF 和 Word): + 您可以通过URL参数加载文档进行对比(支持 PDF 和 Word,使用相对路径): - /monaco-demo?doc1=路径1&doc2=路径2 + /monaco-demo?doc1=相对路径1&doc2=相对路径2
-
PDF示例: /monaco-demo?doc1=documents/contract_v1.pdf&doc2=documents/contract_v2.pdf
-
Word示例: /monaco-demo?doc1=testWork/(最终版)智慧法务平台建设采购项目合同(1).docx&doc2=testWork/(最终版)智慧法务平台建设采购项目合同(2).docx
+
Word示例: /monaco-demo?doc1=testWork/(最终版)智慧法务平台建设采购项目合同(1).docx&doc2=testWork/(最终版)智慧法务平台建设采购项目合同(2).docx
+
PDF示例: /monaco-demo?doc1=testPDF/sample1.pdf&doc2=testPDF/sample2.pdf