完善文档预览的效果修改

This commit is contained in:
2025-04-21 23:02:29 +08:00
parent 5c2c367856
commit cd2f060d87
15 changed files with 718 additions and 565 deletions
+80 -10
View File
@@ -2,7 +2,7 @@
* 文件预览组件
* 显示文档内容和评查点高亮
*/
import { useState, useEffect, useRef } from 'react';
import { useState, useEffect, useRef, ChangeEvent } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
// 设置worker路径为public目录下的worker文件
@@ -11,6 +11,7 @@ pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.js';
// 导入统一的ReviewPoint类型
import { type ReviewPoint } from './';
import { toastService } from '../ui/Toast';
/**
* 自定义样式
@@ -72,10 +73,11 @@ interface FilePreviewProps {
export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, targetPage }: FilePreviewProps) {
const [zoomLevel, setZoomLevel] = useState(100);
const [highlightsVisible, setHighlightsVisible] = useState(true);
// const [highlightsVisible, setHighlightsVisible] = useState(true);
const contentRef = useRef<HTMLDivElement>(null);
const [numPages, setNumPages] = useState<number | null>(null);
const [loadError, setLoadError] = useState<string | null>(null);
const [pageInputValue, setPageInputValue] = useState<string>('');
// 放大文档
const handleZoomIn = () => {
@@ -92,9 +94,9 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, ta
};
// 切换高亮显示
const toggleHighlights = () => {
setHighlightsVisible(!highlightsVisible);
};
// const toggleHighlights = () => {
// setHighlightsVisible(!highlightsVisible);
// };
// 当选中的评查点变化时,滚动到对应位置
// useEffect(() => {
@@ -132,7 +134,7 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, ta
const pageElement = document.getElementById(`page-${newTargetPage}`);
if (pageElement) {
console.log(`跳转到第${newTargetPage}页,对应评查点ID: ${activeReviewPointId}`);
console.log(`跳转到第${newTargetPage}页,对应评查点结果ID: ${activeReviewPointId}`);
pageElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
}
@@ -152,6 +154,40 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, ta
}
};
// 处理页码输入变化
const handlePageInputChange = (e: ChangeEvent<HTMLInputElement>) => {
// 只允许输入数字
const value = e.target.value.replace(/\D/g, '');
setPageInputValue(value);
};
// 处理页码跳转
const handlePageJump = () => {
if (!pageInputValue || !numPages) return;
const targetPageNum = parseInt(pageInputValue, 10);
// 验证页码是否在有效范围内
if (targetPageNum > 0 && targetPageNum <= numPages) {
// 找到目标页面元素并滚动到该位置
const pageElement = document.getElementById(`page-${targetPageNum}`);
if (pageElement) {
pageElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
} else {
// 页码超出范围,显示错误信息或重置输入
toastService.warning(`请输入有效页码 (1-${numPages})`);
setPageInputValue('');
}
};
// 处理回车键跳转
const handlePageInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handlePageJump();
}
};
// PDF文档加载成功回调函数
function onDocumentLoadSuccess({ numPages }: { numPages: number }) {
setNumPages(numPages);
@@ -166,6 +202,13 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, ta
const additionalMargin = Math.max(0, (zoomFactor - 1) * 800); // 800是估计的页面高度
return baseMargin + additionalMargin;
};
// 滚动到顶部
const handleScrollToTop = () => {
if (contentRef.current) {
contentRef.current.scrollTo({ top: 0, behavior: 'smooth' });
}
};
/**
* 渲染PDF文档的所有页面
@@ -224,7 +267,7 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, ta
/>
{/* 渲染评查点高亮区域 */}
{highlightsVisible && pageReviewPoints.map(point => {
{/* {highlightsVisible && pageReviewPoints.map(point => {
// 判断当前评查点是否为激活状态(被选中)
const isActive = point.id === activeReviewPointId;
@@ -249,7 +292,7 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, ta
}}
/>
);
})}
})} */}
</div>
</div>
);
@@ -288,7 +331,14 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, ta
<i className="ri-file-text-line text-primary mr-2"></i>
<span className="font-medium text-primary"></span>
</div>
<div className="file-preview-actions">
<div className="file-preview-actions flex items-center">
<button
className="ant-btn ant-btn-sm ant-btn-default py-0 px-1 text-xs h-5 leading-5 "
onClick={handleScrollToTop}
>
<i className="ri-arrow-up-double-line "></i>
<span className="ml-1"></span>
</button>
<button
className="ant-btn ant-btn-sm ant-btn-default py-0 px-1 text-xs h-5 leading-5"
onClick={handleZoomIn}
@@ -301,13 +351,33 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, ta
>
<i className="ri-zoom-out-line"></i>
</button>
{/* 页码跳转控件 */}
<div className="inline-flex items-center ml-2">
<input
type="text"
className="ant-input ant-input-sm py-0 px-1 text-xs h-5 leading-5 w-10 text-center
focus:outline-none focus:ring-1 focus:ring-green-900"
placeholder="页码"
value={pageInputValue}
onChange={handlePageInputChange}
onKeyDown={handlePageInputKeyDown}
/>
<button
className="ant-btn ant-btn-sm ant-btn-default py-0 px-1 text-xs h-5 leading-5 ml-1"
onClick={handlePageJump}
disabled={!numPages}
>
<i className="ri-arrow-right-line"></i>
</button>
{numPages && <span className="ml-1 text-xs text-gray-500">/ {numPages}</span>}
</div>
{/* <button
className="ant-btn ant-btn-sm ant-btn-default py-0 px-1 text-xs h-5 leading-5"
onClick={toggleHighlights}
>
<i className="ri-mark-pen-line"></i> {highlightsVisible ? '隐藏问题' : '显示问题'}
</button> */}
<span className="ml-2 text-xs text-gray-500">{"比例:"+zoomLevel+"%"}</span>
<span className="ml-2 text-xs text-gray-500 inline-block">{"比例:"+zoomLevel+"%"}</span>
</div>
</div>
<div