修改合同比对demo
This commit is contained in:
+69
-57
@@ -134,6 +134,11 @@ export default function MonacoDemoPage() {
|
|||||||
const [currentDiff, setCurrentDiff] = useState<number>(0);
|
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 [doc1Url, setDoc1Url] = useState<string>('');
|
||||||
const [doc2Url, setDoc2Url] = useState<string>('');
|
const [doc2Url, setDoc2Url] = useState<string>('');
|
||||||
const [doc1Info, setDoc1Info] = useState<DocumentInfo | null>(null);
|
const [doc1Info, setDoc1Info] = useState<DocumentInfo | null>(null);
|
||||||
@@ -222,9 +227,9 @@ export default function MonacoDemoPage() {
|
|||||||
const arrayBuffer = await response.arrayBuffer();
|
const arrayBuffer = await response.arrayBuffer();
|
||||||
|
|
||||||
// 使用 mammoth 提取纯文本
|
// 使用 mammoth 提取纯文本
|
||||||
const result = await mammoth.extractRawText({ arrayBuffer });
|
const textResult = await mammoth.extractRawText({ arrayBuffer });
|
||||||
|
|
||||||
return result.value;
|
return textResult.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 加载文档并提取文本(支持 PDF 和 Word)
|
// 加载文档并提取文本(支持 PDF 和 Word)
|
||||||
@@ -276,6 +281,7 @@ export default function MonacoDemoPage() {
|
|||||||
|
|
||||||
setDocInfo(docInfo);
|
setDocInfo(docInfo);
|
||||||
setTextContent(text);
|
setTextContent(text);
|
||||||
|
|
||||||
toastService.success(`Word文档加载成功!提取了 ${text.length} 个字符`);
|
toastService.success(`Word文档加载成功!提取了 ${text.length} 个字符`);
|
||||||
} else {
|
} else {
|
||||||
toastService.error('不支持的文件类型');
|
toastService.error('不支持的文件类型');
|
||||||
@@ -365,45 +371,33 @@ export default function MonacoDemoPage() {
|
|||||||
}, 100);
|
}, 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)
|
// 从URL参数加载文档(支持 PDF 和 Word)
|
||||||
const loadDocumentsFromUrl = () => {
|
const loadDocumentsFromUrl = () => {
|
||||||
if (typeof window === 'undefined') return;
|
if (typeof window === 'undefined') return;
|
||||||
|
|
||||||
const searchParams = new URLSearchParams(window.location.search);
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
const doc1Path = searchParams.get('doc1') || searchParams.get('pdf1'); // 兼容旧参数名
|
const doc1Param = searchParams.get('doc1') || searchParams.get('pdf1'); // 兼容旧参数名
|
||||||
const doc2Path = searchParams.get('doc2') || searchParams.get('pdf2'); // 兼容旧参数名
|
const doc2Param = searchParams.get('doc2') || searchParams.get('pdf2'); // 兼容旧参数名
|
||||||
|
|
||||||
if (doc1Path || doc2Path) {
|
// 只有在传参时才加载文档,否则使用默认的 mock 数据(示例合同)
|
||||||
|
if (doc1Param || doc2Param) {
|
||||||
setUseExample(false);
|
setUseExample(false);
|
||||||
|
|
||||||
if (doc1Path) {
|
// 文档1
|
||||||
const fullUrl = buildFileUrl(doc1Path);
|
if (doc1Param) {
|
||||||
setDoc1Url(fullUrl);
|
const doc1Url = doc1Param.startsWith('/') ? doc1Param : '/' + doc1Param; // 相对路径,确保以 / 开头
|
||||||
loadDocumentAndExtractText(fullUrl, doc1Path, setDoc1Info, setIsLoadingDoc1, setOriginalText);
|
setDoc1Url(doc1Url);
|
||||||
|
loadDocumentAndExtractText(doc1Url, doc1Param, setDoc1Info, setIsLoadingDoc1, setOriginalText);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc2Path) {
|
// 文档2
|
||||||
const fullUrl = buildFileUrl(doc2Path);
|
if (doc2Param) {
|
||||||
setDoc2Url(fullUrl);
|
const doc2Url = doc2Param.startsWith('/') ? doc2Param : '/' + doc2Param; // 相对路径,确保以 / 开头
|
||||||
loadDocumentAndExtractText(fullUrl, doc2Path, setDoc2Info, setIsLoadingDoc2, setModifiedText);
|
setDoc2Url(doc2Url);
|
||||||
|
loadDocumentAndExtractText(doc2Url, doc2Param, setDoc2Info, setIsLoadingDoc2, setModifiedText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 如果没有传参,则保持 useExample=true,显示默认的 CONTRACT_A 和 CONTRACT_B
|
||||||
};
|
};
|
||||||
|
|
||||||
// 组件挂载时读取URL参数
|
// 组件挂载时读取URL参数
|
||||||
@@ -412,8 +406,46 @@ export default function MonacoDemoPage() {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// 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 (
|
return (
|
||||||
<div className="monaco-demo-page" style={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
<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={{
|
<div style={{
|
||||||
padding: '16px 24px',
|
padding: '16px 24px',
|
||||||
@@ -515,31 +547,11 @@ export default function MonacoDemoPage() {
|
|||||||
<i className="ri-refresh-line"></i>
|
<i className="ri-refresh-line"></i>
|
||||||
重置示例
|
重置示例
|
||||||
</button>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 文档加载信息 */}
|
{/* 文档加载信息 */}
|
||||||
{!useExample && (doc1Info || doc2Info || isLoadingDoc1 || isLoadingDoc2) && (
|
{!useExample && (doc1Info || doc2Info || isLoadingDoc1 || isLoadingDoc2) && 2==1 && (
|
||||||
<div style={{
|
<div style={{
|
||||||
padding: '12px 24px',
|
padding: '12px 24px',
|
||||||
backgroundColor: '#fff3cd',
|
backgroundColor: '#fff3cd',
|
||||||
@@ -624,16 +636,16 @@ export default function MonacoDemoPage() {
|
|||||||
<div style={{ flex: 1 }}>
|
<div style={{ flex: 1 }}>
|
||||||
<strong>差异高亮说明:</strong>
|
<strong>差异高亮说明:</strong>
|
||||||
<ul style={{ margin: '4px 0 0 0', paddingLeft: '20px' }}>
|
<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: '#dc3545', fontWeight: 'bold' }}>红色</span>:删除的内容</li>
|
<li><span style={{ color: '#28a745', fontWeight: 'bold' }}>右侧绿色背景</span>:修改版本的内容(新增或修改后的内容)</li>
|
||||||
<li><span style={{ color: '#ffc107', fontWeight: 'bold' }}>黄色背景</span>:修改的行内差异</li>
|
<li><span style={{ color: '#666', fontWeight: 'bold' }}>深色高亮</span>:行内具体修改的字符差异</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{useExample && (
|
{useExample && (
|
||||||
<div style={{ marginTop: '12px', paddingTop: '12px', borderTop: '1px solid #b3d9ff' }}>
|
<div style={{ marginTop: '12px', paddingTop: '12px', borderTop: '1px solid #b3d9ff' }}>
|
||||||
<strong>💡 使用提示:</strong>
|
<strong>💡 使用提示:</strong>
|
||||||
<div style={{ marginTop: '4px' }}>
|
<div style={{ marginTop: '4px' }}>
|
||||||
您可以通过URL参数加载文档进行对比(支持 PDF 和 Word):
|
您可以通过URL参数加载文档进行对比(支持 PDF 和 Word,使用相对路径):
|
||||||
<code style={{
|
<code style={{
|
||||||
display: 'block',
|
display: 'block',
|
||||||
marginTop: '4px',
|
marginTop: '4px',
|
||||||
@@ -643,11 +655,11 @@ export default function MonacoDemoPage() {
|
|||||||
fontSize: '12px',
|
fontSize: '12px',
|
||||||
wordBreak: 'break-all'
|
wordBreak: 'break-all'
|
||||||
}}>
|
}}>
|
||||||
/monaco-demo?doc1=路径1&doc2=路径2
|
/monaco-demo?doc1=相对路径1&doc2=相对路径2
|
||||||
</code>
|
</code>
|
||||||
<div style={{ marginTop: '4px', fontSize: '12px' }}>
|
<div style={{ marginTop: '4px', fontSize: '12px' }}>
|
||||||
<div>PDF示例: <code>/monaco-demo?doc1=documents/contract_v1.pdf&doc2=documents/contract_v2.pdf</code></div>
|
<div>Word示例: <code>/monaco-demo?doc1=testWork/(最终版)智慧法务平台建设采购项目合同(1).docx&doc2=testWork/(最终版)智慧法务平台建设采购项目合同(2).docx</code></div>
|
||||||
<div style={{ marginTop: '2px' }}>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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user