隐藏上传文件入口,交叉评查的文件查看添加防抖点击,升级pdf加载组件版本优化清晰度
This commit is contained in:
@@ -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" // 添加边框和阴影样式
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
{/* 文件类型选择和上传表单 */}
|
{/* 文件类型选择和上传表单 */}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Vendored
+44
-44
@@ -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;
|
||||||
}
|
// }
|
||||||
Generated
+2726
-3649
File diff suppressed because it is too large
Load Diff
+1
-5
@@ -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",
|
||||||
|
|||||||
Vendored
+4
-5
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user