隐藏上传文件入口,交叉评查的文件查看添加防抖点击,升级pdf加载组件版本优化清晰度

This commit is contained in:
jiangao
2025-09-30 14:32:00 +08:00
parent 25c8c75aa5
commit 9ec6d30573
14 changed files with 2872 additions and 3735 deletions
@@ -9,6 +9,7 @@ import { LoadingIndicator } from '../ui/SkeletonScreen';
import { updateDocumentAuditStatus, type TaskDocument } from '~/api/cross-checking/cross-files'; // 更新导入 import { updateDocumentAuditStatus, type TaskDocument } from '~/api/cross-checking/cross-files'; // 更新导入
import { toastService } from '../ui/Toast'; import { toastService } from '../ui/Toast';
import { formatDate } from '~/utils'; import { formatDate } from '~/utils';
import {useRef, useState} from "react";
// 导出样式链接 // 导出样式链接
export const links = () => []; export const links = () => [];
@@ -42,7 +43,16 @@ export function DocumentListModal({
onPageChange, onPageChange,
onPageSizeChange onPageSizeChange
}: DocumentListModalProps) { }: DocumentListModalProps) {
// 查看按钮防抖
const [isnavigating,setIsnavigating] = useState(false)
const viewDebounceRef = useRef<number | null>(null)
const handleViewClickDebounced = (fileId: string, auditStatus: number | null) => {
if(viewDebounceRef.current) return;
viewDebounceRef.current = window.setTimeout(()=>{
viewDebounceRef.current = null;
},1000);
void handleReviewFileClick(fileId, auditStatus);
}
// 查看评查文件 // 查看评查文件
const handleReviewFileClick = async (fileId: string, auditStatus: number | null) => { const handleReviewFileClick = async (fileId: string, auditStatus: number | null) => {
// 检查audit_status是否为0,如果是则更新为2 // 检查audit_status是否为0,如果是则更新为2
@@ -61,6 +71,7 @@ export function DocumentListModal({
// 如果有自定义的查看处理函数,则调用它 // 如果有自定义的查看处理函数,则调用它
if (onViewFile) { if (onViewFile) {
setIsnavigating(true)
onViewFile(fileId); onViewFile(fileId);
} }
}; };
@@ -250,11 +261,11 @@ export function DocumentListModal({
type="default" type="default"
size="small" size="small"
icon="ri-eye-line" icon="ri-eye-line"
onClick={() => handleReviewFileClick(file.document_id.toString(), file.audit_status)} onClick={() => handleViewClickDebounced(file.document_id.toString(), file.audit_status)}
disabled={file.status !== 'Processed'} disabled={file.status !== 'Processed'}
className="mr-2" className="mr-2"
> >
{isnavigating ? '跳转中...' : '查看'}
</Button> </Button>
</> </>
) )
@@ -334,8 +334,8 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage
{/* 渲染PDF页面组件 */} {/* 渲染PDF页面组件 */}
<Page <Page
pageNumber={i} // 当前页码 pageNumber={i} // 当前页码
renderTextLayer={true} // 用文本层,使文本可选择 renderTextLayer={false} // 用文本层,使文本可选择
renderAnnotationLayer={true} // 用注释层,显示PDF内置注释 renderAnnotationLayer={false} // 用注释层,显示PDF内置注释
className="border border-gray-300 shadow-md" // 添加边框和阴影样式 className="border border-gray-300 shadow-md" // 添加边框和阴影样式
/> />
+13 -1
View File
@@ -240,6 +240,18 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = '' }: Sid
return true; return true;
}); });
// filteredMenuItems = filteredMenuItems.map(item => {
// if(item.children && item.children.length > 0){
// const children = item.children.filter(child => {
// const isUploadByPath = child.path === '/files/upload' || child.path?.startsWith('/files/upload')
// const isUploadByTitle = child.title === '文件上传'
// return !(isUploadByPath || isUploadByTitle)
// })
// return { ...item, children}
// }
// return item
// })
return ( return (
<div className={`sidebar ${collapsed ? 'collapsed' : ''}`}> <div className={`sidebar ${collapsed ? 'collapsed' : ''}`}>
<div className="py-6 px-4 border-b border-gray-100 flex justify-between items-center"> <div className="py-6 px-4 border-b border-gray-100 flex justify-between items-center">
@@ -333,7 +345,7 @@ export function Sidebar({ onToggle, collapsed, userRole, selectedApp = '' }: Sid
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') { if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault(); e.preventDefault();
toggleMenu(item.id, e as unknown as React.MouseEvent); toggleMenu(item.id, (e as unknown) as React.MouseEvent);
} }
}} }}
> >
+9 -5
View File
@@ -8,6 +8,7 @@ import { DOCUMENT_URL } from '~/api/axios-client';
// 设置worker路径为public目录下的worker文件 // 设置worker路径为public目录下的worker文件
// 使用已经下载的兼容版本 (pdfjs-dist v2.12.313) // 使用已经下载的兼容版本 (pdfjs-dist v2.12.313)
// 2025/09/28 使用新版本的pdfjs-dist v4.8.69
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.js'; pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.js';
// 导入统一的ReviewPoint类型 // 导入统一的ReviewPoint类型
@@ -324,8 +325,8 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage
<div <div
className="page-wrapper" className="page-wrapper"
style={{ style={{
transform: `scale(${zoomFactor})`, // 根据zoomLevel应用缩放 // transform: `scale(${zoomFactor})`, // 根据zoomLevel应用缩放
transformOrigin: 'top center', // 缩放原点设置为顶部中心 // transformOrigin: 'top center', // 缩放原点设置为顶部中心
position: 'relative', // 相对定位,作为评查点高亮的定位参考 position: 'relative', // 相对定位,作为评查点高亮的定位参考
display: 'inline-block', // 内联块级元素,宽度由内容决定 display: 'inline-block', // 内联块级元素,宽度由内容决定
margin: '0 auto', // 水平居中 margin: '0 auto', // 水平居中
@@ -334,8 +335,10 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage
{/* 渲染PDF页面组件 */} {/* 渲染PDF页面组件 */}
<Page <Page
pageNumber={i} // 当前页码 pageNumber={i} // 当前页码
renderTextLayer={true} // 启用文本层,使文本可选择 scale={zoomLevel / 100}
renderAnnotationLayer={true} // 启用注释层,显示PDF内置注释 devicePixelRatio={window.devicePixelRatio || 1} //根据设备像素比渲染
renderTextLayer={false} // 停用文本层,使文本可选择
renderAnnotationLayer={false} // 停用注释层,显示PDF内置注释
className="border border-gray-300 shadow-md" // 添加边框和阴影样式 className="border border-gray-300 shadow-md" // 添加边框和阴影样式
/> />
@@ -405,7 +408,8 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage
style={{ style={{
...styles.pdfContainer, ...styles.pdfContainer,
// 当缩放大于100%时设置最小宽度,确保出现横向滚动条 // 当缩放大于100%时设置最小宽度,确保出现横向滚动条
minWidth: zoomLevel > 100 ? `${zoomLevel}%` : '100%', // minWidth: zoomLevel > 100 ? `${zoomLevel}%` : '100%',
width: '100%',
overflow: 'visible' overflow: 'visible'
}} }}
> >
+7 -7
View File
@@ -73,9 +73,9 @@ const portConfigs: Record<string, Partial<ApiConfig>> = {
// 主要 // 主要
// 梅州 // 梅州
'51703': { '51703': {
baseUrl: 'http://10.79.97.17:8000', baseUrl: 'http://nas.7bm.co:8873',
documentUrl: 'http://10.79.97.17:8000/docauditai/', documentUrl: 'http://nas.7bm.co:8873/docauditai/',
uploadUrl: 'http://10.79.97.17:8000/admin/documents' uploadUrl: 'http://nas.7bm.co:8873/admin/documents'
}, },
@@ -139,12 +139,12 @@ const configs: Record<string, ApiConfig> = {
// 测试环境 // 测试环境
testing: { testing: {
baseUrl: 'http://172.16.0.55:8008', baseUrl: 'http://nas.7bm.co:8873',
// baseUrl: 'http://172.16.0.81:3000', // baseUrl: 'http://172.16.0.58:8873',
// baseUrl: 'http://nas.7bm.co:3000', // baseUrl: 'http://nas.7bm.co:3000',
// documentUrl: 'http://172.16.0.81:9000/docauditai/', // documentUrl: 'http://172.16.0.81:9000/docauditai/',
documentUrl: 'http://172.16.0.55:8008/docauditai/', documentUrl: 'http://nas.7bm.co:8873/docauditai/',
uploadUrl: 'http://172.16.0.55:8008/admin/documents', uploadUrl: 'http://nas.7bm.co:8873/admin/documents',
// uploadUrl: 'http://172.16.0.58:8008/admin/documents', // uploadUrl: 'http://172.16.0.58:8008/admin/documents',
// uploadUrl: 'http://172.16.0.58:8008/admin/documents', // uploadUrl: 'http://172.16.0.58:8008/admin/documents',
oauth: { oauth: {
+7 -5
View File
@@ -207,7 +207,7 @@ export default function CrossCheckingUpload() {
const [taskInfo, setTaskInfo] = useState({ const [taskInfo, setTaskInfo] = useState({
name: '', name: '',
date: '', date: '',
type: '市局交叉评查', type: '市局交叉评查',
}); });
// 步骤2状态 // 步骤2状态
const [groupChecked, setGroupChecked] = useState<string[]>(userInfo?.user_id ? [`user_${userInfo.user_id}`] : []); const [groupChecked, setGroupChecked] = useState<string[]>(userInfo?.user_id ? [`user_${userInfo.user_id}`] : []);
@@ -681,13 +681,15 @@ export default function CrossCheckingUpload() {
</div> </div>
<div className="form-group"> <div className="form-group">
<label htmlFor="task-type"></label> <label htmlFor="task-type"></label>
<input <select
id="task-type" id="task-type"
className="form-input" className="form-select"
value={taskInfo.type} value={taskInfo.type}
onChange={e => setTaskInfo({ ...taskInfo, type: e.target.value })} onChange={e => setTaskInfo({ ...taskInfo, type: e.target.value })}
placeholder="请输入任务类型" >
/> <option value="市局间交叉评查"></option>
<option value="区局间交叉评查"></option>
</select>
</div> </div>
<div className="flex justify-between items-center mt-6"> <div className="flex justify-between items-center mt-6">
<Button <Button
+2 -2
View File
@@ -375,8 +375,8 @@ export default function DocumentEdit() {
{/* 渲染PDF页面组件 */} {/* 渲染PDF页面组件 */}
<Page <Page
pageNumber={i} // 当前页码 pageNumber={i} // 当前页码
renderTextLayer={true} // 用文本层,使文本可选择 renderTextLayer={false} // 用文本层,使文本可选择
renderAnnotationLayer={true} // 用注释层,显示PDF内置注释 renderAnnotationLayer={false} // 用注释层,显示PDF内置注释
className="border border-gray-300 shadow-md" // 添加边框和阴影样式 className="border border-gray-300 shadow-md" // 添加边框和阴影样式
/> />
</div> </div>
+19 -5
View File
@@ -25,6 +25,7 @@ import {
} from "~/api/files/files-upload"; } from "~/api/files/files-upload";
import { updateDocumentAuditStatus } from "~/api/evaluation_points/rules-files"; import { updateDocumentAuditStatus } from "~/api/evaluation_points/rules-files";
import { links as fileTypeTagLinks } from "~/components/ui/FileTypeTag"; import { links as fileTypeTagLinks } from "~/components/ui/FileTypeTag";
import { useRevalidator} from "react-router-dom";
export function links() { export function links() {
return [ return [
@@ -34,11 +35,11 @@ export function links() {
} }
// 面包屑导航 // 面包屑导航
export const handle = { // export const handle = {
breadcrumb: () => { // breadcrumb: () => {
return '上传文件' // return '上传文件'
} // }
} // }
export const meta: MetaFunction = () => { export const meta: MetaFunction = () => {
return [ return [
@@ -286,6 +287,10 @@ export async function loader({ request }: LoaderFunctionArgs) {
// 文件上传页面组件 // 文件上传页面组件
export default function FilesUpload() { export default function FilesUpload() {
const [isNavigating, setIsNavigating] = useState(false)
const revalidator = useRevalidator()
// 获取 sessionStorage 中的 reviewType 值 // 获取 sessionStorage 中的 reviewType 值
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const [reviewType, setReviewType] = useState<string | null>(null); const [reviewType, setReviewType] = useState<string | null>(null);
@@ -2084,12 +2089,21 @@ export default function FilesUpload() {
} }
]; ];
// 返回上一级防抖处理
const handleBackClick = () =>{
if(isNavigating) return;
setIsNavigating(true)
navigate(-1)
revalidator.revalidate()
}
return ( return (
<div className="file-upload-page"> <div className="file-upload-page">
{/* 页面头部 */} {/* 页面头部 */}
<div className="page-header"> <div className="page-header">
<h2 className="page-title"></h2> <h2 className="page-title"></h2>
<button className="ant-btn ant-btn-default flex items-center my-2" onClick={()=>handleBackClick()}><i className="ri-arrow-left-line"></i>{isNavigating ? '返回中...' : '返回'}</button>
</div> </div>
{/* 文件类型选择和上传表单 */} {/* 文件类型选择和上传表单 */}
+2 -2
View File
@@ -325,8 +325,8 @@ export default function Documents() {
<div className="text-center text-gray-500 text-sm mb-2"> {i} </div> <div className="text-center text-gray-500 text-sm mb-2"> {i} </div>
<Page <Page
pageNumber={i} pageNumber={i}
renderTextLayer={true} renderTextLayer={false}
renderAnnotationLayer={true} renderAnnotationLayer={false}
className="border border-gray-300 shadow-md" className="border border-gray-300 shadow-md"
/> />
</div> </div>
+44 -44
View File
@@ -1,44 +1,44 @@
declare module 'react-pdf' { // declare module 'react-pdf' {
import * as React from 'react'; // import * as React from 'react';
//
interface TextItem { // interface TextItem {
str: string; // str: string;
transform: number[]; // transform: number[];
width: number; // width: number;
height: number; // height: number;
fontName: string; // fontName: string;
} // }
//
export interface DocumentProps { // export interface DocumentProps {
file: string | Uint8Array | ArrayBuffer; // file: string | Uint8Array | ArrayBuffer;
onLoadSuccess?: ({ numPages }: { numPages: number }) => void; // onLoadSuccess?: ({ numPages }: { numPages: number }) => void;
onLoadError?: (error: Error) => void; // onLoadError?: (error: Error) => void;
className?: string; // className?: string;
error?: React.ReactNode; // error?: React.ReactNode;
noData?: React.ReactNode; // noData?: React.ReactNode;
loading?: React.ReactNode; // loading?: React.ReactNode;
children?: React.ReactNode; // children?: React.ReactNode;
} // }
//
export interface PageProps { // export interface PageProps {
pageNumber: number; // pageNumber: number;
renderTextLayer?: boolean; // renderTextLayer?: boolean;
renderAnnotationLayer?: boolean; // renderAnnotationLayer?: boolean;
className?: string; // className?: string;
customTextRenderer?: (textItem: TextItem) => string; // customTextRenderer?: (textItem: TextItem) => string;
} // }
//
export const Document: React.FC<DocumentProps>; // export const Document: React.FC<DocumentProps>;
export const Page: React.FC<PageProps>; // export const Page: React.FC<PageProps>;
export const pdfjs: { // export const pdfjs: {
GlobalWorkerOptions: { // GlobalWorkerOptions: {
workerSrc: string; // workerSrc: string;
}; // };
version: string; // version: string;
}; // };
} // }
//
declare module '*.css' { // declare module '*.css' {
const content: Record<string, string>; // const content: Record<string, string>;
export default content; // export default content;
} // }
+2726 -3649
View File
File diff suppressed because it is too large Load Diff
+1 -5
View File
@@ -19,9 +19,6 @@
"@ant-design/icons": "^5.6.1", "@ant-design/icons": "^5.6.1",
"@codemirror/lang-javascript": "^6.2.3", "@codemirror/lang-javascript": "^6.2.3",
"@codemirror/theme-one-dark": "^6.1.2", "@codemirror/theme-one-dark": "^6.1.2",
"@react-pdf-viewer/core": "^3.12.0",
"@react-pdf-viewer/highlight": "^3.12.0",
"@react-pdf-viewer/search": "^3.12.0",
"@remix-run/node": "^2.16.2", "@remix-run/node": "^2.16.2",
"@remix-run/react": "^2.16.2", "@remix-run/react": "^2.16.2",
"@remix-run/serve": "^2.16.2", "@remix-run/serve": "^2.16.2",
@@ -43,14 +40,13 @@
"katex": "^0.16.22", "katex": "^0.16.22",
"mammoth": "^1.9.0", "mammoth": "^1.9.0",
"pdf-lib": "^1.17.1", "pdf-lib": "^1.17.1",
"pdfjs-dist": "^3.11.174",
"pg": "^8.14.1", "pg": "^8.14.1",
"pm2": "^6.0.8", "pm2": "^6.0.8",
"prismjs": "^1.30.0", "prismjs": "^1.30.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-pdf": "^5.7.2", "react-pdf": "^9.2.1",
"rehype-katex": "^7.0.1", "rehype-katex": "^7.0.1",
"remark-breaks": "^4.0.0", "remark-breaks": "^4.0.0",
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
+4 -5
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long