feat: 1. 接入CollaboraViewer选中的高亮效果,清除高亮功能,页面销毁自动清除高亮。
2. 合同模板对比接入monaco editor的效果。 3. 添加交叉评查的案卷类型的数据查询。 fix: 1. 修复文档列表的打开模态框蒙板层显示效果。
This commit is contained in:
@@ -42,7 +42,7 @@ export async function callPythonScript(
|
||||
const verbose = options?.verbose ?? true;
|
||||
|
||||
if (verbose) {
|
||||
console.log('[CallCustomScript] 调用 Python 脚本:', { scriptFile, functionName, args });
|
||||
// console.log('[CallCustomScript] 调用 Python 脚本:', { scriptFile, functionName, args });
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -72,7 +72,7 @@ export async function callPythonScript(
|
||||
cleanup();
|
||||
|
||||
if (verbose) {
|
||||
console.log('[CallCustomScript] 收到 Python 脚本响应:', data);
|
||||
// console.log('[CallCustomScript] 收到 Python 脚本响应:', data);
|
||||
}
|
||||
|
||||
const result = parseScriptResponse(data, verbose);
|
||||
@@ -107,7 +107,7 @@ export async function callPythonScript(
|
||||
};
|
||||
|
||||
if (verbose) {
|
||||
console.log('[CallCustomScript] 发送 PostMessage:', message);
|
||||
// console.log('[CallCustomScript] 发送 PostMessage:', message);
|
||||
}
|
||||
|
||||
iframeWindow.postMessage(JSON.stringify(message), '*');
|
||||
@@ -130,12 +130,12 @@ function parseScriptResponse(data: PostMessageResponse, verbose: boolean): Scrip
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
console.log('[CallCustomScript] 解析结果:', {
|
||||
commandName: values.commandName,
|
||||
unoSuccess: values.success,
|
||||
resultRaw: values.result,
|
||||
resultExtracted: resultValue,
|
||||
});
|
||||
// console.log('[CallCustomScript] 解析结果:', {
|
||||
// commandName: values.commandName,
|
||||
// unoSuccess: values.success,
|
||||
// resultRaw: values.result,
|
||||
// resultExtracted: resultValue,
|
||||
// });
|
||||
}
|
||||
|
||||
if (values.success === false) {
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
* @encoding UTF-8
|
||||
*/
|
||||
|
||||
import { useRef, forwardRef, useImperativeHandle, useState } from 'react';
|
||||
import { useRef, forwardRef, useImperativeHandle, useState, useEffect } from 'react';
|
||||
import type { CollaboraViewerProps, CollaboraViewerHandle } from './types';
|
||||
import { useCollaboraConfig, useDocumentReady, useCollaboraUnoCommands } from './hooks';
|
||||
import { sendUnoCommand } from './Uno';
|
||||
import { highlightText } from './lib/Highlightselecttext';
|
||||
import { highlightText as performTextHighlight } from './lib/Highlightselecttext';
|
||||
import { clearHighlights } from './lib/ClearHighlight';
|
||||
import {
|
||||
unoScrollToTop,
|
||||
@@ -41,10 +41,14 @@ export const CollaboraViewer = forwardRef<CollaboraViewerHandle, CollaboraViewer
|
||||
mode = 'view',
|
||||
userId = 'guest',
|
||||
userName = '',
|
||||
targetPage,
|
||||
highlightText,
|
||||
},
|
||||
ref
|
||||
) {
|
||||
const iframeRef = useRef<HTMLIFrameElement>(null);
|
||||
// 保存 iframe 的 contentWindow 引用,用于组件卸载时清除高亮
|
||||
const iframeWindowRef = useRef<Window | null>(null);
|
||||
|
||||
// 高亮测试面板状态
|
||||
const [highlightTextInput, setHighlightTextInput] = useState('');
|
||||
@@ -89,17 +93,119 @@ export const CollaboraViewer = forwardRef<CollaboraViewerHandle, CollaboraViewer
|
||||
// 2. 监听文档加载状态
|
||||
const { isDocumentLoaded } = useDocumentReady(iframeRef);
|
||||
|
||||
// 2.5. 保存 iframe window 引用并在文档加载时清除所有高亮
|
||||
useEffect(() => {
|
||||
if (isDocumentLoaded && iframeRef.current?.contentWindow) {
|
||||
iframeWindowRef.current = iframeRef.current.contentWindow;
|
||||
console.log('[CollaboraViewer] 已保存 iframe window 引用');
|
||||
|
||||
// 🔥 文档加载完成后主动清除一次高亮(防止缓存的高亮状态)
|
||||
console.log('[CollaboraViewer] 🧹 文档加载完成,清除可能存在的缓存高亮');
|
||||
clearHighlights(iframeRef.current.contentWindow, {
|
||||
color: 16776960,
|
||||
timeout: 5000,
|
||||
}).then((result) => {
|
||||
if (result.count && result.count > 0) {
|
||||
console.log(`[CollaboraViewer] ✓ 清除了 ${result.count} 个缓存的高亮区域`);
|
||||
} else {
|
||||
console.log('[CollaboraViewer] ✓ 文档无缓存高亮,已确认干净');
|
||||
}
|
||||
}).catch(error => {
|
||||
console.warn('[CollaboraViewer] ⚠️ 清除缓存高亮失败:', error);
|
||||
});
|
||||
}
|
||||
}, [isDocumentLoaded]);
|
||||
|
||||
// 3. UNO 命令封装
|
||||
const unoCommands = useCollaboraUnoCommands(iframeRef);
|
||||
|
||||
// 4. 暴露接口给父组件
|
||||
// 4. 暴露接口给父组件(包括清除高亮方法)
|
||||
useImperativeHandle(ref, () => ({
|
||||
unoCommands,
|
||||
isReady: isDocumentLoaded,
|
||||
mode,
|
||||
getIframeWindow: () => iframeRef.current?.contentWindow || null,
|
||||
clearAllHighlights: async () => {
|
||||
const savedWindow = iframeWindowRef.current || iframeRef.current?.contentWindow;
|
||||
if (savedWindow) {
|
||||
console.log('[CollaboraViewer] 🧹 父组件调用清除高亮');
|
||||
await clearHighlights(savedWindow, {
|
||||
color: 16776960,
|
||||
timeout: 5000,
|
||||
});
|
||||
console.log('[CollaboraViewer] ✓ 清除高亮完成');
|
||||
} else {
|
||||
console.warn('[CollaboraViewer] ⚠️ 无法清除高亮:iframe window 不可用');
|
||||
}
|
||||
},
|
||||
}), [unoCommands, isDocumentLoaded, mode]);
|
||||
|
||||
// 5. 监听 targetPage 和 highlightText 变化,自动跳转并高亮
|
||||
useEffect(() => {
|
||||
// 如果文档未加载完成,不执行跳转和高亮
|
||||
if (!isDocumentLoaded || !iframeRef.current?.contentWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果有高亮文本,执行高亮操作
|
||||
if (highlightText && highlightText.trim() !== '') {
|
||||
const performHighlight = async () => {
|
||||
try {
|
||||
const iframeWindow = iframeRef.current!.contentWindow!;
|
||||
const textToHighlight = highlightText.trim();
|
||||
|
||||
// 🔥 在高亮新内容之前,先清除之前的所有高亮
|
||||
console.log('[CollaboraViewer] 清除旧高亮...');
|
||||
await clearHighlights(iframeWindow, {
|
||||
color: 16776960, // 黄色
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
// 短暂延迟后执行新高亮,确保清除操作完成
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
// 执行新高亮
|
||||
await performTextHighlight(
|
||||
iframeWindow,
|
||||
textToHighlight,
|
||||
{ page: targetPage }
|
||||
);
|
||||
console.log(`[CollaboraViewer] 已高亮文本: "${textToHighlight}"${targetPage ? ` (第${targetPage}页)` : ''}`);
|
||||
} catch (error) {
|
||||
console.error('[CollaboraViewer] 高亮失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
performHighlight();
|
||||
}
|
||||
}, [targetPage, highlightText, isDocumentLoaded]);
|
||||
|
||||
// 6. 组件销毁时清除所有高亮(使用保存的 window 引用)
|
||||
useEffect(() => {
|
||||
// 返回清理函数,在组件卸载时执行
|
||||
return () => {
|
||||
const savedWindow = iframeWindowRef.current;
|
||||
if (savedWindow) {
|
||||
console.log('[CollaboraViewer] 🔥 组件即将销毁,立即清除所有高亮');
|
||||
|
||||
// 立即触发清除操作,不等待异步完成
|
||||
// 使用 void 关键字表示我们不关心 Promise 的结果
|
||||
void clearHighlights(savedWindow, {
|
||||
color: 16776960, // 黄色
|
||||
timeout: 3000,
|
||||
}).then(() => {
|
||||
console.log('[CollaboraViewer] ✓ 组件销毁时高亮清除成功');
|
||||
}).catch(error => {
|
||||
console.error('[CollaboraViewer] ✗ 组件销毁时清除高亮失败:', error);
|
||||
});
|
||||
|
||||
// 清空引用
|
||||
iframeWindowRef.current = null;
|
||||
} else {
|
||||
console.warn('[CollaboraViewer] ⚠️ 组件销毁时未找到保存的 window 引用');
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 加载中状态
|
||||
if (loading) {
|
||||
@@ -185,7 +291,7 @@ export const CollaboraViewer = forwardRef<CollaboraViewerHandle, CollaboraViewer
|
||||
return;
|
||||
}
|
||||
|
||||
await highlightText(
|
||||
await performTextHighlight(
|
||||
iframeRef.current.contentWindow,
|
||||
highlightTextInput.trim(),
|
||||
{ page }
|
||||
|
||||
@@ -13,6 +13,12 @@ export {
|
||||
unoScrollToTop
|
||||
} from './navigation';
|
||||
|
||||
// 缩放功能
|
||||
export {
|
||||
unoZoomIn,
|
||||
unoZoomOut,
|
||||
unoSetZoom
|
||||
} from './zoom';
|
||||
|
||||
// 页数信息
|
||||
export {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Collabora Online 缩放功能
|
||||
*
|
||||
* @encoding UTF-8
|
||||
*/
|
||||
|
||||
import { sendUnoCommand } from '../Uno';
|
||||
|
||||
/**
|
||||
* 放大文档
|
||||
* @param iframeWindow - iframe 的 contentWindow
|
||||
*/
|
||||
export function unoZoomIn(iframeWindow: Window): void {
|
||||
sendUnoCommand(iframeWindow, '.uno:ZoomPlus');
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩小文档
|
||||
* @param iframeWindow - iframe 的 contentWindow
|
||||
*/
|
||||
export function unoZoomOut(iframeWindow: Window): void {
|
||||
sendUnoCommand(iframeWindow, '.uno:ZoomMinus');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缩放比例
|
||||
* @param iframeWindow - iframe 的 contentWindow
|
||||
* @param percentage - 缩放比例(例如:100 表示 100%)
|
||||
*/
|
||||
export function unoSetZoom(iframeWindow: Window, percentage: number): void {
|
||||
sendUnoCommand(iframeWindow, '.uno:Zoom', {
|
||||
Zoom: {
|
||||
type: 'long',
|
||||
value: percentage,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -34,6 +34,10 @@ export interface CollaboraViewerProps {
|
||||
userId?: string;
|
||||
/** 用户名称 */
|
||||
userName?: string;
|
||||
/** 目标页码(用于自动跳转和高亮) */
|
||||
targetPage?: number;
|
||||
/** 要高亮的文本内容 */
|
||||
highlightText?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,4 +54,6 @@ export interface CollaboraViewerHandle {
|
||||
mode: 'view' | 'edit';
|
||||
/** 获取 iframe 的 contentWindow (用于发送 PostMessage) */
|
||||
getIframeWindow: () => Window | null;
|
||||
/** 清除所有高亮 */
|
||||
clearAllHighlights: () => Promise<void>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user