修改合同比对demo

This commit is contained in:
2025-11-25 15:04:05 +08:00
parent 0ed6f0aaf4
commit 6064941265
+69 -57
View File
@@ -134,6 +134,11 @@ export default function MonacoDemoPage() {
const [currentDiff, setCurrentDiff] = useState<number>(0);
// 文档相关状态
// 默认使用的测试文档路径(相对路径)
// 注意:文件名中使用的是中文全角括号()而不是英文半角括号()
const DEFAULT_DOC1_URL = '/testWork/(最终版)智慧法务平台建设采购项目合同(1).docx';
const DEFAULT_DOC2_URL = '/testWork/(最终版)智慧法务平台建设采购项目合同(2).docx';
const [doc1Url, setDoc1Url] = useState<string>('');
const [doc2Url, setDoc2Url] = useState<string>('');
const [doc1Info, setDoc1Info] = useState<DocumentInfo | null>(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 (
<div className="monaco-demo-page" style={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
{/* 字符级差异高亮样式 - 加深高亮颜色 */}
<style>{`
/* 修改后的文本(绿色背景)- 字符级差异 */
.monaco-diff-editor .char-insert {
background-color: rgba(100, 150, 50, 0.6) !important;
}
/* 删除的文本(红色背景)- 字符级差异 */
.monaco-diff-editor .char-delete {
background-color: rgba(200, 50, 50, 0.5) !important;
}
/* 内联文本差异 */
.monaco-diff-editor .line-insert .char-insert {
background-color: rgba(100, 150, 50, 0.7) !important;
}
.monaco-diff-editor .line-delete .char-delete {
background-color: rgba(200, 50, 50, 0.6) !important;
}
`}</style>
{/* 页面头部 */}
<div style={{
padding: '16px 24px',
@@ -515,31 +547,11 @@ export default function MonacoDemoPage() {
<i className="ri-refresh-line"></i>
</button>
{/* 未来扩展:上传按钮 */}
<button
disabled
style={{
padding: '6px 12px',
backgroundColor: '#e0e0e0',
border: '1px solid #d0d0d0',
borderRadius: '4px',
cursor: 'not-allowed',
fontSize: '14px',
display: 'flex',
alignItems: 'center',
gap: '6px',
opacity: 0.5
}}
>
<i className="ri-upload-2-line"></i>
</button>
</div>
</div>
{/* 文档加载信息 */}
{!useExample && (doc1Info || doc2Info || isLoadingDoc1 || isLoadingDoc2) && (
{!useExample && (doc1Info || doc2Info || isLoadingDoc1 || isLoadingDoc2) && 2==1 && (
<div style={{
padding: '12px 24px',
backgroundColor: '#fff3cd',
@@ -624,16 +636,16 @@ export default function MonacoDemoPage() {
<div style={{ flex: 1 }}>
<strong></strong>
<ul style={{ margin: '4px 0 0 0', paddingLeft: '20px' }}>
<li><span style={{ color: '#28a745', fontWeight: 'bold' }}>绿</span></li>
<li><span style={{ color: '#dc3545', fontWeight: 'bold' }}></span></li>
<li><span style={{ color: '#ffc107', fontWeight: 'bold' }}></span></li>
<li><span style={{ color: '#dc3545', fontWeight: 'bold' }}></span></li>
<li><span style={{ color: '#28a745', fontWeight: 'bold' }}>绿</span></li>
<li><span style={{ color: '#666', fontWeight: 'bold' }}></span></li>
</ul>
{useExample && (
<div style={{ marginTop: '12px', paddingTop: '12px', borderTop: '1px solid #b3d9ff' }}>
<strong>💡 使</strong>
<div style={{ marginTop: '4px' }}>
URL参数加载文档进行对比 PDF Word
URL参数加载文档进行对比 PDF Word使
<code style={{
display: 'block',
marginTop: '4px',
@@ -643,11 +655,11 @@ export default function MonacoDemoPage() {
fontSize: '12px',
wordBreak: 'break-all'
}}>
/monaco-demo?doc1=1&doc2=2
/monaco-demo?doc1=1&doc2=2
</code>
<div style={{ marginTop: '4px', fontSize: '12px' }}>
<div>PDF示例: <code>/monaco-demo?doc1=documents/contract_v1.pdf&doc2=documents/contract_v2.pdf</code></div>
<div style={{ marginTop: '2px' }}>Word示例: <code>/monaco-demo?doc1=testWork/()(1).docx&doc2=testWork/()(2).docx</code></div>
<div>Word示例: <code>/monaco-demo?doc1=testWork/(1).docx&doc2=testWork/(2).docx</code></div>
<div style={{ marginTop: '2px' }}>PDF示例: <code>/monaco-demo?doc1=testPDF/sample1.pdf&doc2=testPDF/sample2.pdf</code></div>
</div>
</div>
</div>