完善文档预览的效果修改
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user