合并代码
This commit is contained in:
+11
-11
@@ -90,12 +90,12 @@ axiosInstance.interceptors.request.use(
|
|||||||
const token = localStorage.getItem('access_token');
|
const token = localStorage.getItem('access_token');
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers.Authorization = `Bearer ${token}`;
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
console.log('🔑 [Request Interceptor] 添加Authorization头:', {
|
// console.log('🔑 [Request Interceptor] 添加Authorization头:', {
|
||||||
url: config.url,
|
// url: config.url,
|
||||||
method: config.method,
|
// method: config.method,
|
||||||
hasToken: !!token,
|
// hasToken: !!token,
|
||||||
tokenPreview: token.substring(0, 20) + '...'
|
// tokenPreview: token.substring(0, 20) + '...'
|
||||||
});
|
// });
|
||||||
} else {
|
} else {
|
||||||
console.warn('⚠️ [Request Interceptor] 没有找到access_token:', {
|
console.warn('⚠️ [Request Interceptor] 没有找到access_token:', {
|
||||||
url: config.url,
|
url: config.url,
|
||||||
@@ -127,11 +127,11 @@ export class AuthenticationError extends Error {
|
|||||||
*/
|
*/
|
||||||
axiosInstance.interceptors.response.use(
|
axiosInstance.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
console.log('✅ [Response Interceptor] 请求成功:', {
|
// console.log('✅ [Response Interceptor] 请求成功:', {
|
||||||
url: response.config.url,
|
// url: response.config.url,
|
||||||
status: response.status,
|
// status: response.status,
|
||||||
statusText: response.statusText
|
// statusText: response.statusText
|
||||||
});
|
// });
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
|||||||
@@ -3,19 +3,14 @@
|
|||||||
* 显示文档内容和评查点高亮
|
* 显示文档内容和评查点高亮
|
||||||
*/
|
*/
|
||||||
import { useState, useEffect, useRef, ChangeEvent } from 'react';
|
import { useState, useEffect, useRef, ChangeEvent } from 'react';
|
||||||
import { pdfjs } from 'react-pdf';
|
|
||||||
import { DOCUMENT_URL } from '~/api/axios-client';
|
|
||||||
import { CollaboraViewer, type CollaboraViewerHandle } from '~/components/collabora/CollaboraViewer';
|
import { CollaboraViewer, type CollaboraViewerHandle } from '~/components/collabora/CollaboraViewer';
|
||||||
import { requestPageInfo, customGotoPage } from '~/components/collabora/lib';
|
import { requestPageInfo, customGotoPage } from '~/components/collabora/lib';
|
||||||
import { PdfPreview } from './previewComponents/PdfPreview';
|
import { PdfPreview } from './previewComponents/PdfPreview';
|
||||||
|
|
||||||
// 设置worker路径为public目录下的worker文件
|
|
||||||
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.js';
|
|
||||||
|
|
||||||
// 导入统一的ReviewPoint类型
|
|
||||||
import { type ReviewPoint } from './';
|
|
||||||
import { toastService } from '../ui/Toast';
|
import { toastService } from '../ui/Toast';
|
||||||
|
|
||||||
|
// 直接从ReviewPointsList导入类型,避免循环依赖
|
||||||
|
import { type ReviewPoint } from './ReviewPointsList';
|
||||||
|
|
||||||
// 定义文档内容类型
|
// 定义文档内容类型
|
||||||
interface FileContent {
|
interface FileContent {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -68,34 +63,24 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage
|
|||||||
const isDocx = fileExtension === 'docx';
|
const isDocx = fileExtension === 'docx';
|
||||||
const isPdf = fileExtension === 'pdf';
|
const isPdf = fileExtension === 'pdf';
|
||||||
|
|
||||||
// 如果是PDF文件,直接使用PdfPreview组件
|
// ✅ 将所有hooks移到条件return之前,确保遵守React Hooks规则
|
||||||
if (isPdf && real_path) {
|
// Refs
|
||||||
// console.log('fileContent', fileContent)
|
|
||||||
// console.log('activeReviewPointResultId', activeReviewPointResultId)
|
|
||||||
const pageOffset = fileContent.ocrResult?.__meta?.page_offset || 0;
|
|
||||||
return (
|
|
||||||
<PdfPreview
|
|
||||||
filePath={real_path}
|
|
||||||
targetPage={targetPage}
|
|
||||||
charPositions={charPositions}
|
|
||||||
isStructuredView={isStructuredView}
|
|
||||||
activeReviewPointResultId={activeReviewPointResultId}
|
|
||||||
pageOffset={pageOffset}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// DOCX 和其他文件类型继续使用原有逻辑
|
|
||||||
const contentRef = useRef<HTMLDivElement>(null);
|
const contentRef = useRef<HTMLDivElement>(null);
|
||||||
const collaboraViewerRef = useRef<CollaboraViewerHandle>(null);
|
const collaboraViewerRef = useRef<CollaboraViewerHandle>(null);
|
||||||
|
const prevTargetPageRef = useRef<number | undefined>(undefined);
|
||||||
|
const lastMousePosRef = useRef({ x: 0, y: 0 });
|
||||||
|
|
||||||
|
// States
|
||||||
const [numPages, setNumPages] = useState<number | null>(null);
|
const [numPages, setNumPages] = useState<number | null>(null);
|
||||||
const [pageInputValue, setPageInputValue] = useState<string>('');
|
const [pageInputValue, setPageInputValue] = useState<string>('');
|
||||||
|
const [dragMode, setDragMode] = useState(false);
|
||||||
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
|
const [dragCursor, setDragCursor] = useState('default');
|
||||||
|
|
||||||
|
// ✅ 将所有useEffect移到条件return之前
|
||||||
// DOCX 页数获取: 使用 requestPageInfo 方法
|
// DOCX 页数获取: 使用 requestPageInfo 方法
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isDocx) return;
|
if (!isDocx || isPdf) return; // PDF文件不需要执行
|
||||||
|
|
||||||
// console.log('[FilePreview] DOCX 文档加载,尝试获取页数');
|
|
||||||
|
|
||||||
let intervalCleared = false;
|
let intervalCleared = false;
|
||||||
|
|
||||||
@@ -108,7 +93,6 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('[FilePreview] Collabora 已就绪,尝试获取页数');
|
|
||||||
clearInterval(checkInterval);
|
clearInterval(checkInterval);
|
||||||
intervalCleared = true;
|
intervalCleared = true;
|
||||||
|
|
||||||
@@ -132,13 +116,97 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage
|
|||||||
return () => {
|
return () => {
|
||||||
clearInterval(checkInterval);
|
clearInterval(checkInterval);
|
||||||
};
|
};
|
||||||
}, [isDocx]);
|
}, [isDocx, isPdf]);
|
||||||
|
|
||||||
// 拖拽状态管理(仅用于 DOCX)
|
// 监听鼠标离开窗口事件
|
||||||
const [dragMode, setDragMode] = useState(false);
|
useEffect(() => {
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
if (isPdf) return; // PDF不需要拖拽功能
|
||||||
const [dragCursor, setDragCursor] = useState('default');
|
|
||||||
const lastMousePosRef = useRef({ x: 0, y: 0 });
|
const handleMouseLeave = () => {
|
||||||
|
if (dragMode && isDragging) {
|
||||||
|
setIsDragging(false);
|
||||||
|
setDragCursor('grab');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseUp = () => {
|
||||||
|
if (!dragMode) return;
|
||||||
|
setIsDragging(false);
|
||||||
|
setDragCursor('grab');
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mouseleave', handleMouseLeave);
|
||||||
|
document.addEventListener('mouseup', handleMouseUp as EventListener);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mouseleave', handleMouseLeave);
|
||||||
|
document.removeEventListener('mouseup', handleMouseUp as EventListener);
|
||||||
|
};
|
||||||
|
}, [isDragging, dragMode, isPdf]);
|
||||||
|
|
||||||
|
// 处理页面跳转
|
||||||
|
useEffect(() => {
|
||||||
|
if (isPdf) return; // PDF由PdfPreview处理
|
||||||
|
|
||||||
|
// 如果有目标页码,并且与上次相同,提示用户
|
||||||
|
if(targetPage && numPages && targetPage <= numPages && targetPage === prevTargetPageRef.current){
|
||||||
|
// toastService.success(`已跳转至目标页码`);
|
||||||
|
}
|
||||||
|
// 如果有目标页码,并且与上次不同或activeReviewPointId变化了,则执行跳转
|
||||||
|
if (targetPage && numPages && targetPage <= numPages) {
|
||||||
|
prevTargetPageRef.current = targetPage;
|
||||||
|
let newTargetPage = targetPage;
|
||||||
|
|
||||||
|
// 页码偏移量
|
||||||
|
try {
|
||||||
|
// 安全地访问ocrResult
|
||||||
|
if (fileContent.ocrResult && fileContent.ocrResult.__meta && fileContent.ocrResult.__meta.page_offset) {
|
||||||
|
// 可以根据需要使用page_offset调整目标页面
|
||||||
|
newTargetPage = targetPage + fileContent.ocrResult.__meta.page_offset;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("访问ocrResult时出错:", error);
|
||||||
|
toastService.error("访问ocrResult时出错:" + (error instanceof Error ? error.message : '未知错误'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageElementId = `page-${newTargetPage}${isStructuredView ? '-structured' : ''}`;
|
||||||
|
|
||||||
|
const pageElement = document.getElementById(pageElementId);
|
||||||
|
if (pageElement) {
|
||||||
|
pageElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
|
} else {
|
||||||
|
console.warn(`未找到页面元素: ${pageElementId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [targetPage, numPages, fileContent, activeReviewPointResultId, isStructuredView, isPdf]);
|
||||||
|
|
||||||
|
// 调试日志
|
||||||
|
console.log('[FilePreview] 组件渲染', {
|
||||||
|
real_path,
|
||||||
|
fileExtension,
|
||||||
|
isDocx,
|
||||||
|
isPdf,
|
||||||
|
hasPath: !!fileContent.path,
|
||||||
|
hasTemplatePath: !!fileContent.template_contract_path
|
||||||
|
});
|
||||||
|
|
||||||
|
// 如果是PDF文件,直接使用PdfPreview组件
|
||||||
|
if (isPdf && real_path) {
|
||||||
|
console.log('[FilePreview] 渲染PDF预览', { real_path, targetPage, charPositions });
|
||||||
|
const pageOffset = fileContent.ocrResult?.__meta?.page_offset || 0;
|
||||||
|
return (
|
||||||
|
<PdfPreview
|
||||||
|
filePath={real_path}
|
||||||
|
targetPage={targetPage}
|
||||||
|
charPositions={charPositions}
|
||||||
|
isStructuredView={isStructuredView}
|
||||||
|
activeReviewPointResultId={activeReviewPointResultId}
|
||||||
|
pageOffset={pageOffset}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOCX 和其他文件类型继续使用原有逻辑
|
||||||
|
|
||||||
// 放大文档(仅用于 DOCX)
|
// 放大文档(仅用于 DOCX)
|
||||||
const handleZoomIn = () => {
|
const handleZoomIn = () => {
|
||||||
@@ -209,66 +277,7 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage
|
|||||||
setIsDragging(false);
|
setIsDragging(false);
|
||||||
setDragCursor('grab');
|
setDragCursor('grab');
|
||||||
};
|
};
|
||||||
|
|
||||||
// 监听鼠标离开窗口事件
|
|
||||||
useEffect(() => {
|
|
||||||
const handleMouseLeave = () => {
|
|
||||||
if (dragMode && isDragging) {
|
|
||||||
setIsDragging(false);
|
|
||||||
setDragCursor('grab');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('mouseleave', handleMouseLeave);
|
|
||||||
document.addEventListener('mouseup', handleMouseUp as EventListener);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener('mouseleave', handleMouseLeave);
|
|
||||||
document.removeEventListener('mouseup', handleMouseUp as EventListener);
|
|
||||||
};
|
|
||||||
}, [isDragging, dragMode]);
|
|
||||||
|
|
||||||
// 处理页面跳转
|
|
||||||
const prevTargetPageRef = useRef<number | undefined>(undefined);
|
|
||||||
useEffect(() => {
|
|
||||||
// 调试信息:记录组件状态
|
|
||||||
// console.log(`FilePreview更新 - isStructuredView:${isStructuredView}, targetPage:${targetPage}, activeReviewPointResultId:${activeReviewPointResultId}, numPages:${numPages}`);
|
|
||||||
|
|
||||||
// 如果有目标页码,并且与上次相同,提示用户
|
|
||||||
if(targetPage && numPages && targetPage <= numPages && targetPage === prevTargetPageRef.current){
|
|
||||||
// toastService.success(`已跳转至目标页码`);
|
|
||||||
}
|
|
||||||
// 如果有目标页码,并且与上次不同或activeReviewPointId变化了,则执行跳转
|
|
||||||
if (targetPage && numPages && targetPage <= numPages) {
|
|
||||||
// if (targetPage && numPages && targetPage <= numPages && (targetPage !== prevTargetPageRef.current || activeReviewPointResultId)) {
|
|
||||||
prevTargetPageRef.current = targetPage;
|
|
||||||
let newTargetPage = targetPage;
|
|
||||||
|
|
||||||
// 页码偏移量
|
|
||||||
try {
|
|
||||||
// 安全地访问ocrResult
|
|
||||||
if (fileContent.ocrResult && fileContent.ocrResult.__meta && fileContent.ocrResult.__meta.page_offset) {
|
|
||||||
// 可以根据需要使用page_offset调整目标页面
|
|
||||||
newTargetPage = targetPage + fileContent.ocrResult.__meta.page_offset;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("访问ocrResult时出错:", error);
|
|
||||||
toastService.error("访问ocrResult时出错:" + (error instanceof Error ? error.message : '未知错误'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const pageElementId = `page-${newTargetPage}${isStructuredView ? '-structured' : ''}`;
|
|
||||||
// console.log(`尝试跳转到元素ID: ${pageElementId}`);
|
|
||||||
|
|
||||||
const pageElement = document.getElementById(pageElementId);
|
|
||||||
if (pageElement) {
|
|
||||||
// console.log(`跳转到第${newTargetPage}页,对应评查点结果ID: ${activeReviewPointResultId}`);
|
|
||||||
pageElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
||||||
} else {
|
|
||||||
console.warn(`未找到页面元素: ${pageElementId}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [targetPage, numPages, fileContent, activeReviewPointResultId, isStructuredView]);
|
|
||||||
|
|
||||||
// 获取评查点对应的样式类
|
// 获取评查点对应的样式类
|
||||||
// const getHighlightClass = (status: string) => {
|
// const getHighlightClass = (status: string) => {
|
||||||
// switch (status) {
|
// switch (status) {
|
||||||
|
|||||||
+44
-18
@@ -178,8 +178,10 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const id = url.searchParams.get('id') || undefined;
|
const id = url.searchParams.get('id') || undefined;
|
||||||
const previousRoute = url.searchParams.get('previousRoute') || '';
|
const previousRoute = url.searchParams.get('previousRoute') || '';
|
||||||
// console.log("id-------",id);
|
// console.log("[Reviews Loader] 开始加载,id:", id, "previousRoute:", previousRoute);
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
|
console.error("[Reviews Loader] 文件ID不能为空");
|
||||||
return Response.json({ result: false, message: '文件ID不能为空' });
|
return Response.json({ result: false, message: '文件ID不能为空' });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,16 +192,13 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
// 获取评查点数据,传递request对象
|
// 获取评查点数据,传递request对象
|
||||||
const reviewData = await getReviewPoints(id, request);
|
const reviewData = await getReviewPoints(id, request);
|
||||||
|
|
||||||
// console.log("documentData-------",JSON.stringify(documentData.data,null,2));
|
|
||||||
// console.log("reviewData-------",JSON.stringify('data' in reviewData ? reviewData.data : '',null,2));
|
|
||||||
if ('error' in reviewData && reviewData.error) {
|
if ('error' in reviewData && reviewData.error) {
|
||||||
console.error("获取评查点数据错误:", reviewData.error);
|
console.error("[Reviews Loader] 获取评查点数据错误:", reviewData.error);
|
||||||
return Response.json({ result: false, message: reviewData.error });
|
return Response.json({ result: false, message: reviewData.error });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确保reviewData有效且具有预期的属性
|
// 确保reviewData有效且具有预期的属性
|
||||||
if ('document' in reviewData && 'data' in reviewData && 'reviewInfo' in reviewData && 'stats' in reviewData) {
|
if ('document' in reviewData && 'data' in reviewData && 'reviewInfo' in reviewData && 'stats' in reviewData) {
|
||||||
// console.log("reviewData-------",JSON.stringify(reviewData.data));
|
|
||||||
return Response.json({
|
return Response.json({
|
||||||
previousRoute: previousRoute,
|
previousRoute: previousRoute,
|
||||||
document: reviewData.document,
|
document: reviewData.document,
|
||||||
@@ -211,12 +210,13 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
frontendJWT
|
frontendJWT
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.error("返回的评查数据格式不正确",JSON.stringify(reviewData,null,2));
|
console.error("[Reviews Loader] 返回的评查数据格式不正确,完整数据:", JSON.stringify(reviewData, null, 2));
|
||||||
return Response.json({ result: false, message: '返回的评查数据格式不正确' });
|
return Response.json({ result: false, message: '返回的评查数据格式不正确' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取评查数据失败:', error);
|
console.error('[Reviews Loader] 获取评查数据失败:', error);
|
||||||
return Response.json({ result: false, message: '获取评查数据失败' });
|
console.error('[Reviews Loader] 错误堆栈:', error instanceof Error ? error.stack : '无堆栈信息');
|
||||||
|
return Response.json({ result: false, message: `获取评查数据失败: ${error instanceof Error ? error.message : '未知错误'}` });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ export async function action({ request }: ActionFunctionArgs) {
|
|||||||
const formData = await request.formData();
|
const formData = await request.formData();
|
||||||
const intent = formData.get("intent") as string;
|
const intent = formData.get("intent") as string;
|
||||||
|
|
||||||
console.log('Action接收到请求, intent:', intent);
|
// console.log('Action接收到请求, intent:', intent);
|
||||||
|
|
||||||
if (intent === "updateReviewResult") {
|
if (intent === "updateReviewResult") {
|
||||||
const reviewPointResultId = formData.get("reviewPointResultId") as string;
|
const reviewPointResultId = formData.get("reviewPointResultId") as string;
|
||||||
@@ -292,8 +292,18 @@ export async function action({ request }: ActionFunctionArgs) {
|
|||||||
export default function ReviewDetails() {
|
export default function ReviewDetails() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const loaderData = useLoaderData<typeof loader>();
|
const loaderData = useLoaderData<typeof loader>();
|
||||||
|
|
||||||
|
// 调试:查看loaderData内容 - 强制刷新
|
||||||
|
console.log('[Reviews Component] loaderData keys:', Object.keys(loaderData));
|
||||||
|
console.log('[Reviews Component] loaderData:', loaderData);
|
||||||
|
|
||||||
const fetcher = useFetcher();
|
const fetcher = useFetcher();
|
||||||
const { document, reviewPoints, statistics, reviewInfo, comparison_document, frontendJWT } = loaderData;
|
const { document, reviewPoints, statistics, reviewInfo, comparison_document, frontendJWT } = loaderData;
|
||||||
|
|
||||||
|
// 调试:查看解构后的数据
|
||||||
|
console.log('[Reviews Component] 解构后的document:', document);
|
||||||
|
console.log('[Reviews Component] 解构后的reviewPoints length:', reviewPoints?.length);
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false); // 已经通过loader加载了数据,不需要再显示加载状态
|
const [isLoading, setIsLoading] = useState(false); // 已经通过loader加载了数据,不需要再显示加载状态
|
||||||
const [activeTab, setActiveTab] = useState<string>('preview'); // 'preview', 'analysis', 'fileinfo'
|
const [activeTab, setActiveTab] = useState<string>('preview'); // 'preview', 'analysis', 'fileinfo'
|
||||||
const [reviewData, setReviewData] = useState<ReviewData | null>(null);
|
const [reviewData, setReviewData] = useState<ReviewData | null>(null);
|
||||||
@@ -306,10 +316,15 @@ export default function ReviewDetails() {
|
|||||||
newStatus: string;
|
newStatus: string;
|
||||||
message: string;
|
message: string;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
|
||||||
// loader 数据加载出错
|
// loader 数据加载出错
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
loadingBarService.hide();
|
loadingBarService.hide();
|
||||||
|
console.log('[Reviews Component] useEffect检查loaderData:', {
|
||||||
|
hasResultKey: Object.keys(loaderData).find(key => key === 'result'),
|
||||||
|
resultValue: loaderData.result,
|
||||||
|
willNavigateBack: Object.keys(loaderData).find(key => key === 'result') && !loaderData.result
|
||||||
|
});
|
||||||
if(Object.keys(loaderData).find(key => key === 'result') && !loaderData.result){
|
if(Object.keys(loaderData).find(key => key === 'result') && !loaderData.result){
|
||||||
messageService.show({
|
messageService.show({
|
||||||
title: '错误',
|
title: '错误',
|
||||||
@@ -717,15 +732,26 @@ export default function ReviewDetails() {
|
|||||||
<div className="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:space-x-4">
|
<div className="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:space-x-4">
|
||||||
{/* 左侧:文件预览 */}
|
{/* 左侧:文件预览 */}
|
||||||
<div className="w-full lg:w-[65%]">
|
<div className="w-full lg:w-[65%]">
|
||||||
<FilePreview
|
{(() => {
|
||||||
fileContent={document}
|
console.log('[Reviews] 准备渲染FilePreview', {
|
||||||
reviewPoints={reviewData.reviewPoints}
|
hasDocument: !!document,
|
||||||
activeReviewPointResultId={activeReviewPointResultId}
|
documentPath: document?.path,
|
||||||
targetPage={targetPage}
|
targetPage,
|
||||||
charPositions={charPositions}
|
hasCharPositions: !!charPositions,
|
||||||
/>
|
charPositionsLength: charPositions?.length
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<FilePreview
|
||||||
|
fileContent={document}
|
||||||
|
reviewPoints={reviewData.reviewPoints}
|
||||||
|
activeReviewPointResultId={activeReviewPointResultId}
|
||||||
|
targetPage={targetPage}
|
||||||
|
charPositions={charPositions}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 右侧:评查结果 */}
|
{/* 右侧:评查结果 */}
|
||||||
<div className="w-full lg:w-[35%]">
|
<div className="w-full lg:w-[35%]">
|
||||||
<ReviewPointsList
|
<ReviewPointsList
|
||||||
|
|||||||
Reference in New Issue
Block a user