删除所有console.log输出,优化评查结果的表格的显示,添加新的页码获取逻辑

This commit is contained in:
2025-06-02 18:55:00 +08:00
parent 820baa5b22
commit b02978508d
71 changed files with 862 additions and 572 deletions
+19 -12
View File
@@ -3,7 +3,7 @@ import { useNavigate, Form } from '@remix-run/react';
import { type MetaFunction, type ActionFunctionArgs, LoaderFunctionArgs, redirect } from "@remix-run/node";
import styles from "~/styles/pages/home.css?url";
import dayjs from 'dayjs';
// import { getUserSession, logout } from "~/root";
import { getUserSession, logout } from "~/root";
export const links = () => [
{ rel: "stylesheet", href: styles }
@@ -22,22 +22,21 @@ export async function action({ request }: ActionFunctionArgs) {
const intent = formData.get("intent");
if (intent === "logout") {
// return logout(request);
return logout(request);
}
return null;
}
// 验证用户登录状态
// export async function loader({ request }: LoaderFunctionArgs) {
// const { isAuthenticated } = await getUserSession(request);
export async function loader({ request }: LoaderFunctionArgs) {
const { isAuthenticated } = await getUserSession(request);
// if (!isAuthenticated) {
// return redirect("/login");
// }
// return Response.json({ isAuthenticated });
// }
if (!isAuthenticated) {
return redirect("/login");
}
return null;
}
export default function Index() {
const navigate = useNavigate();
@@ -68,6 +67,7 @@ export default function Index() {
// 处理模块点击
const handleModuleClick = (path: string) => {
// console.log("导航到路径:", path);
navigate(path);
};
@@ -80,6 +80,13 @@ export default function Index() {
// 处理登出
const handleLogout = () => {
// 清除sessionStorage中的用户角色信息
if (typeof window !== 'undefined') {
sessionStorage.removeItem('userRole');
// 可以根据需要清除其他会话数据
sessionStorage.clear();
}
// 使用Form组件提交登出请求
const form = document.getElementById('logout-form') as HTMLFormElement;
if (form) {
@@ -127,8 +134,8 @@ export default function Index() {
{/* 合同管理模块 */}
<div
className="module-card"
onClick={() => handleModuleClick('/documents')}
onKeyDown={(e) => handleKeyDown('/documents', e)}
onClick={() => handleModuleClick('/contract-template/search')}
onKeyDown={(e) => handleKeyDown('/contract-template/search', e)}
role="button"
tabIndex={0}
aria-label="合同管理"
+4 -4
View File
@@ -45,8 +45,8 @@ export async function loader({ params }: LoaderFunctionArgs) {
}
// 添加调试信息
console.log('模板详情数据:', response.data);
console.log('分类信息:', response.data.category);
// console.log('模板详情数据:', response.data);
// console.log('分类信息:', response.data.category);
return { template: response.data };
} catch (error) {
@@ -90,7 +90,7 @@ export default function ContractTemplateDetail() {
link.click();
document.body.removeChild(link);
console.log('开始下载文件:', cleanFileName);
// console.log('开始下载文件:', cleanFileName);
} catch (error) {
console.error('下载文件失败:', error);
alert('下载失败,请稍后重试');
@@ -108,7 +108,7 @@ export default function ContractTemplateDetail() {
};
const handlePreview = () => {
console.log('预览模板:', template.id);
// console.log('预览模板:', template.id);
// 页面内预览,滚动到预览区域
const previewElement = document.getElementById('template-preview');
if (previewElement) {
+1 -1
View File
@@ -296,7 +296,7 @@ export default function DocumentEdit() {
const onDocumentLoadSuccess = ({numPages}: {numPages: number}) => {
setNumPages(numPages);
console.log('文档加载成功', numPages);
// console.log('文档加载成功', numPages);
}
const renderDocumentContent = () => {
+77 -77
View File
@@ -121,7 +121,7 @@ async function uploadFileToServer(
isTestDocument: boolean
): Promise<FileUploadResponse> {
// 在实际应用中,这里会使用fetch或axios发送请求到后端API
console.log(`[API] 上传文件: ${fileName}, 大小: ${binaryData.byteLength} 字节`);
// console.log(`[API] 上传文件: ${fileName}, 大小: ${binaryData.byteLength} 字节`);
try {
// 使用封装的上传函数
@@ -206,7 +206,7 @@ export async function action({ request }: ActionFunctionArgs) {
// 获取文件信息
if (fileUpload) {
console.log(`接收到文件: ${fileUpload.name}, 大小: ${fileUpload.size}, 类型: ${fileUpload.type}`);
// console.log(`接收到文件: ${fileUpload.name}, 大小: ${fileUpload.size}, 类型: ${fileUpload.type}`);
}
// 注意: 在实际的Remix action中,我们无法直接处理文件内容
@@ -356,7 +356,7 @@ export default function FilesUpload() {
// useEffect 处理上传队列状态检查定时器 - 只在组件卸载时清除
useEffect(() => {
console.log('设置上传队列状态检查定时器');
// console.log('设置上传队列状态检查定时器');
// 标记组件已挂载
isMountedRef.current = true;
@@ -367,7 +367,7 @@ export default function FilesUpload() {
// 只在组件卸载时清除
return () => {
console.log('组件卸载,清除上传队列状态检查定时器');
// console.log('组件卸载,清除上传队列状态检查定时器');
// 标记组件已卸载
isMountedRef.current = false;
if (statusCheckIntervalRef.current) {
@@ -387,16 +387,16 @@ export default function FilesUpload() {
.filter(file => file.status !== DocumentStatus.PROCESSED && file.id)
.map(file => file.id);
console.log('未完成的文档ID:', incompleteIds);
// console.log('未完成的文档ID:', incompleteIds);
if (incompleteIds.length === 0) {
console.log('没有未完成的文档,跳过状态检查');
// console.log('没有未完成的文档,跳过状态检查');
return;
}
// 获取这些文档的最新状态
const statusResponse = await getDocumentsStatus(incompleteIds);
console.log('状态检查响应:', statusResponse);
// console.log('状态检查响应:', statusResponse);
if (statusResponse.data) {
// 更新队列中的文档状态
@@ -404,7 +404,7 @@ export default function FilesUpload() {
const updatedFiles = prevFiles.map(file => {
const updatedStatus = statusResponse.data.find(doc => doc.id === file.id);
if (updatedStatus) {
console.log(`文档 ${file.id} 状态更新: ${file.status} -> ${updatedStatus.status}`);
// console.log(`文档 ${file.id} 状态更新: ${file.status} -> ${updatedStatus.status}`);
return { ...file, status: updatedStatus.status };
}
return file;
@@ -456,7 +456,7 @@ export default function FilesUpload() {
const value = e.target.value;
// 确保只有选择了有效的文件类型才进行设置
if (value) {
console.log('【调试-handleFileTypeChange】文件类型变更为:', value);
// console.log('【调试-handleFileTypeChange】文件类型变更为:', value);
setFileType(value as FileType);
// 立即清除错误状态
setFileTypeError(null);
@@ -464,12 +464,12 @@ export default function FilesUpload() {
// 检查是否选择了合同类型
const selectedType = documentTypes.find(t => t.id.toString() === value);
const isContract = !!(selectedType && selectedType.name.includes('合同'));
console.log('【调试-handleFileTypeChange】文件类型检查:', {
selectedType,
isContract,
typeName: selectedType?.name,
currentFiles: currentFiles.length
});
// console.log('【调试-handleFileTypeChange】文件类型检查:', {
// selectedType,
// isContract,
// typeName: selectedType?.name,
// currentFiles: currentFiles.length
// });
setIsContractType(isContract);
@@ -480,10 +480,10 @@ export default function FilesUpload() {
// 如果已经有选中的文件,且选择了文件类型,且不是合同类型,则开始上传
if (currentFiles.length > 0 && !isContract) {
console.log('【调试-handleFileTypeChange】自动开始上传非合同类型文件');
// console.log('【调试-handleFileTypeChange】自动开始上传非合同类型文件');
startUpload(currentFiles);
} else if (currentFiles.length > 0 && isContract) {
console.log('【调试-handleFileTypeChange】合同类型需要手动点击开始上传按钮');
// console.log('【调试-handleFileTypeChange】合同类型需要手动点击开始上传按钮');
// 合同类型不自动上传,需要用户先上传主文件和附件,然后点击开始上传按钮
setCurrentFiles([]);
}
@@ -499,11 +499,11 @@ export default function FilesUpload() {
// 处理合同主文件选择
const handleContractMainFilesSelected = (files: FileList) => {
try {
console.log('【调试-handleContractMainFilesSelected】开始处理合同主文件选择, 文件数量:', files.length);
// console.log('【调试-handleContractMainFilesSelected】开始处理合同主文件选择, 文件数量:', files.length);
// 检查组件是否已卸载
if (!isMountedRef.current) {
console.error('【调试-handleContractMainFilesSelected】组件已卸载,取消处理');
// console.error('【调试-handleContractMainFilesSelected】组件已卸载,取消处理');
return;
}
@@ -532,15 +532,15 @@ export default function FilesUpload() {
}
if (validFiles.length > 0 && isMountedRef.current) {
console.log('【调试-handleContractMainFilesSelected】有效文件数量:', validFiles.length);
console.log('【调试-handleContractMainFilesSelected】有效文件:', validFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
// console.log('【调试-handleContractMainFilesSelected】有效文件数量:', validFiles.length);
// console.log('【调试-handleContractMainFilesSelected】有效文件:', validFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
setContractMainFiles(validFiles);
} else {
console.error('【调试-handleContractMainFilesSelected】没有有效的PDF文件或组件已卸载');
}
} else {
console.log('【调试-handleContractMainFilesSelected】未选择任何文件');
// console.log('【调试-handleContractMainFilesSelected】未选择任何文件');
}
} catch (error) {
console.error('【调试-handleContractMainFilesSelected】处理合同主文件选择时发生错误:', error);
@@ -550,7 +550,7 @@ export default function FilesUpload() {
// 处理合同附件选择
const handleContractAttachmentFilesSelected = (files: FileList) => {
try {
console.log('【调试-handleContractAttachmentFilesSelected】开始处理合同附件选择, 文件数量:', files.length);
// console.log('【调试-handleContractAttachmentFilesSelected】开始处理合同附件选择, 文件数量:', files.length);
// 检查组件是否已卸载
if (!isMountedRef.current) {
@@ -583,15 +583,15 @@ export default function FilesUpload() {
}
if (validFiles.length > 0 && isMountedRef.current) {
console.log('【调试-handleContractAttachmentFilesSelected】有效文件数量:', validFiles.length);
console.log('【调试-handleContractAttachmentFilesSelected】有效文件:', validFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
// console.log('【调试-handleContractAttachmentFilesSelected】有效文件数量:', validFiles.length);
// console.log('【调试-handleContractAttachmentFilesSelected】有效文件:', validFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
setContractAttachmentFiles(validFiles);
} else {
console.error('【调试-handleContractAttachmentFilesSelected】没有有效的PDF文件或组件已卸载');
}
} else {
console.log('【调试-handleContractAttachmentFilesSelected】未选择任何文件');
// console.log('【调试-handleContractAttachmentFilesSelected】未选择任何文件');
}
} catch (error) {
console.error('【调试-handleContractAttachmentFilesSelected】处理合同附件选择时发生错误:', error);
@@ -601,11 +601,11 @@ export default function FilesUpload() {
// 检查并准备上传
const checkAndPrepareUpload = (mainFiles: File[], attachmentFiles: File[]) => {
try {
console.log('【调试-checkAndPrepareUpload】开始检查并准备上传文件', {
mainFilesCount: mainFiles.length,
attachmentFilesCount: attachmentFiles.length,
fileType
});
// console.log('【调试-checkAndPrepareUpload】开始检查并准备上传文件', {
// mainFilesCount: mainFiles.length,
// attachmentFilesCount: attachmentFiles.length,
// fileType
// });
// 检查组件是否已卸载
if (!isMountedRef.current) {
@@ -624,14 +624,14 @@ export default function FilesUpload() {
const selectedType = documentTypes.find(t => t.id.toString() === fileType);
const isContract = !!(selectedType && selectedType.name.includes('合同'));
console.log('【调试-checkAndPrepareUpload】文件类型检查', {
selectedType,
isContract,
typeName: selectedType?.name
});
// console.log('【调试-checkAndPrepareUpload】文件类型检查', {
// selectedType,
// isContract,
// typeName: selectedType?.name
// });
if (isContract) {
console.log('【调试-checkAndPrepareUpload】合同文档类型特殊处理');
// console.log('【调试-checkAndPrepareUpload】合同文档类型特殊处理');
// 检查主文件
if(mainFiles.length === 0) {
@@ -641,11 +641,11 @@ export default function FilesUpload() {
}
// 记录主文件和附件文件信息
console.log('【调试-checkAndPrepareUpload】合同主文件:', mainFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
// console.log('【调试-checkAndPrepareUpload】合同主文件:', mainFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
if (attachmentFiles.length > 0) {
console.log('【调试-checkAndPrepareUpload】合同附件文件:', attachmentFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
// console.log('【调试-checkAndPrepareUpload】合同附件文件:', attachmentFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
} else {
console.log('【调试-checkAndPrepareUpload】无合同附件文件');
// console.log('【调试-checkAndPrepareUpload】无合同附件文件');
}
}
@@ -658,7 +658,7 @@ export default function FilesUpload() {
allFiles = [...allFiles, ...attachmentFiles];
}
console.log('【调试-checkAndPrepareUpload】合并文件后总数:', allFiles.length);
// console.log('【调试-checkAndPrepareUpload】合并文件后总数:', allFiles.length);
// 检查组件是否已卸载
if (!isMountedRef.current) {
@@ -670,7 +670,7 @@ export default function FilesUpload() {
setCurrentFiles(allFiles);
// 将准备上传的操作移到这里,暂时不执行
console.log('【调试-checkAndPrepareUpload】准备上传', allFiles.length, '个文件');
// console.log('【调试-checkAndPrepareUpload】准备上传', allFiles.length, '个文件');
if (fileType) {
try {
@@ -680,7 +680,7 @@ export default function FilesUpload() {
return;
}
console.log('【调试-checkAndPrepareUpload】开始调用startUpload函数');
// console.log('【调试-checkAndPrepareUpload】开始调用startUpload函数');
// 使用 setTimeout 延迟调用,确保状态已更新
setTimeout(() => {
@@ -725,7 +725,7 @@ export default function FilesUpload() {
// 开始上传文件
const startUpload = async (files: File[]) => {
try {
console.log('【调试-startUpload】开始上传过程,文件数量:', files.length);
// console.log('【调试-startUpload】开始上传过程,文件数量:', files.length);
// 检查组件是否已卸载
if (!isMountedRef.current) {
@@ -750,7 +750,7 @@ export default function FilesUpload() {
const totalSize = files.reduce((sum, file) => sum + file.size, 0);
let uploadedSize = 0;
console.log('【调试-startUpload】总文件大小:', formatFileSize(totalSize));
// console.log('【调试-startUpload】总文件大小:', formatFileSize(totalSize));
// 更新步骤状态
const updatedSteps = [...processingSteps];
@@ -761,12 +761,12 @@ export default function FilesUpload() {
if (isMountedRef.current) {
setProcessingSteps(updatedSteps);
} else {
console.log('【调试-startUpload】组件已卸载,不更新处理步骤');
// console.log('【调试-startUpload】组件已卸载,不更新处理步骤');
return;
}
// 转换文件为二进制格式
console.log("【调试-startUpload】开始转换文件到二进制格式...");
// console.log("【调试-startUpload】开始转换文件到二进制格式...");
// 模拟上传进度
if (progressIntervalRef.current) {
@@ -795,21 +795,21 @@ export default function FilesUpload() {
for (const file of files) {
try {
console.log(`【调试-startUpload】准备上传文件: ${file.name}, 大小: ${formatFileSize(file.size)}`);
// console.log(`【调试-startUpload】准备上传文件: ${file.name}, 大小: ${formatFileSize(file.size)}`);
// 转换文件为二进制格式
console.log(`【调试-startUpload】开始转换文件 ${file.name} 为二进制格式`);
// console.log(`【调试-startUpload】开始转换文件 ${file.name} 为二进制格式`);
let binaryData: ArrayBuffer;
try {
binaryData = await uploadFileToBinary(file);
console.log(`【调试-startUpload】文件 ${file.name} 二进制转换成功,大小: ${binaryData.byteLength} 字节`);
// console.log(`【调试-startUpload】文件 ${file.name} 二进制转换成功,大小: ${binaryData.byteLength} 字节`);
} catch (binaryError) {
console.error(`【调试-startUpload】文件 ${file.name} 二进制转换失败:`, binaryError);
throw new Error(`文件 ${file.name} 转换失败: ${binaryError instanceof Error ? binaryError.message : '未知错误'}`);
}
let response: FileUploadResponse;
console.log(`【调试-startUpload】开始上传文件 ${file.name} 到服务器,文件类型: ${fileType}`);
// console.log(`【调试-startUpload】开始上传文件 ${file.name} 到服务器,文件类型: ${fileType}`);
try {
// 上传文件
@@ -819,7 +819,7 @@ export default function FilesUpload() {
return { success: false, error: '组件已卸载' } as FileUploadResponse;
}
console.log(`【调试-startUpload】准备上传文件 ${file.name} 到服务器`);
// console.log(`【调试-startUpload】准备上传文件 ${file.name} 到服务器`);
// 使用Promise.race添加超时处理
const uploadPromise = uploadFileToServer(
@@ -848,7 +848,7 @@ export default function FilesUpload() {
return;
}
console.log(`【调试-startUpload】文件 ${file.name} 上传响应:`, response);
// console.log(`【调试-startUpload】文件 ${file.name} 上传响应:`, response);
} catch (error) {
// 检查组件是否已卸载
if (!isMountedRef.current) {
@@ -884,7 +884,7 @@ export default function FilesUpload() {
}
};
console.log(`【调试-startUpload】文件 ${file.name} 上传成功,文件ID: ${newFile.id}`);
// console.log(`【调试-startUpload】文件 ${file.name} 上传成功,文件ID: ${newFile.id}`);
uploadedFiles.push(newFile);
} catch (fileError) {
console.error(`【调试-startUpload】处理文件 ${file.name} 时发生错误:`, fileError);
@@ -916,14 +916,14 @@ export default function FilesUpload() {
};
});
console.log(`【调试-startUpload】所有文件上传完成,更新队列`);
// console.log(`【调试-startUpload】所有文件上传完成,更新队列`);
setQueueFiles(prev => [...newDocuments, ...prev]);
// 设置当前文件为已上传的文件
setCompletedFiles(uploadedFiles);
// 完成上传后开始处理流程
console.log(`【调试-startUpload】开始文件处理流程`);
// console.log(`【调试-startUpload】开始文件处理流程`);
startProcessing(uploadedFiles);
} catch (error) {
console.error("【调试-startUpload】文件上传过程发生错误:", error);
@@ -959,7 +959,7 @@ export default function FilesUpload() {
// 开始处理上传的文件
const startProcessing = (files: UploadedFile[]) => {
try {
console.log('【调试-startProcessing】开始处理上传的文件:', files.length, '个文件');
// console.log('【调试-startProcessing】开始处理上传的文件:', files.length, '个文件');
// 检查组件是否已卸载
if (!isMountedRef.current) {
@@ -981,14 +981,14 @@ export default function FilesUpload() {
// 获取文件ID列表
const fileIds = files.map(file => file.id).filter(id => id > 0);
console.log('【调试-startProcessing】文件ID列表:', fileIds);
// console.log('【调试-startProcessing】文件ID列表:', fileIds);
if (fileIds.length === 0) {
console.error('【调试-startProcessing】没有有效的文件ID,无法开始处理');
throw new Error('没有有效的文件ID,无法开始处理');
}
console.log('【调试-startProcessing】开始处理文件,设置文件处理进度定时器');
// console.log('【调试-startProcessing】开始处理文件,设置文件处理进度定时器');
// 清除之前的进度定时器(如果存在)
if (progressIntervalRef.current) {
@@ -997,7 +997,7 @@ export default function FilesUpload() {
// 立即开始检查状态
try {
console.log('【调试-startProcessing】立即开始检查处理状态');
// console.log('【调试-startProcessing】立即开始检查处理状态');
checkProcessingStatus(fileIds);
} catch (statusError) {
console.error('【调试-startProcessing】首次检查状态失败:', statusError);
@@ -1005,7 +1005,7 @@ export default function FilesUpload() {
// 设置文件处理进度定时器,每10秒检查一次状态
progressIntervalRef.current = setInterval(() => {
console.log('【调试-startProcessing】文件处理进度定时器触发,检查文件状态');
// console.log('【调试-startProcessing】文件处理进度定时器触发,检查文件状态');
try {
checkProcessingStatus(fileIds);
} catch (intervalError) {
@@ -1050,7 +1050,7 @@ export default function FilesUpload() {
// 检查文件处理状态
const checkProcessingStatus = async (fileIds: number[]) => {
try {
console.log('【调试-checkProcessingStatus】检查文件处理状态:', fileIds);
// console.log('【调试-checkProcessingStatus】检查文件处理状态:', fileIds);
// 检查组件是否已卸载
if (!isMountedRef.current) {
@@ -1060,12 +1060,12 @@ export default function FilesUpload() {
// 如果没有文件ID,不执行检查
if (!fileIds.length) {
console.log('【调试-checkProcessingStatus】没有需要检查的文件');
// console.log('【调试-checkProcessingStatus】没有需要检查的文件');
return;
}
// 获取文件状态
console.log('【调试-checkProcessingStatus】发送请求获取文件状态');
// console.log('【调试-checkProcessingStatus】发送请求获取文件状态');
const response = await getDocumentsStatus(fileIds);
if (response.error) {
@@ -1073,26 +1073,26 @@ export default function FilesUpload() {
return;
}
console.log('【调试-checkProcessingStatus】文件状态响应:', response.data);
// console.log('【调试-checkProcessingStatus】文件状态响应:', response.data);
if (!response.data || !response.data.length) {
console.log('【调试-checkProcessingStatus】没有返回文件状态数据');
// console.log('【调试-checkProcessingStatus】没有返回文件状态数据');
return;
}
// 检查是否所有文件都已完成处理
const allCompleted = response.data.every(doc => doc.status === DocumentStatus.PROCESSED);
console.log('【调试-checkProcessingStatus】文件处理状态:', { allCompleted, statusList: response.data.map(doc => doc.status) });
// console.log('【调试-checkProcessingStatus】文件处理状态:', { allCompleted, statusList: response.data.map(doc => doc.status) });
// 更新步骤状态
if (allCompleted) {
console.log('【调试-checkProcessingStatus】所有文件处理完成,更新步骤状态为完成');
// console.log('【调试-checkProcessingStatus】所有文件处理完成,更新步骤状态为完成');
// 清除文件处理进度定时器
if (progressIntervalRef.current) {
clearInterval(progressIntervalRef.current);
progressIntervalRef.current = null;
console.log('【调试-checkProcessingStatus】文件处理完成,清除文件处理进度定时器');
// console.log('【调试-checkProcessingStatus】文件处理完成,清除文件处理进度定时器');
}
// 更新为全部完成状态
@@ -1112,7 +1112,7 @@ export default function FilesUpload() {
} else {
// 根据当前状态更新步骤
const currentStatus = response.data[0].status;
console.log('【调试-checkProcessingStatus】根据当前状态更新步骤:', currentStatus);
// console.log('【调试-checkProcessingStatus】根据当前状态更新步骤:', currentStatus);
updateProcessingSteps(currentStatus);
}
@@ -1127,7 +1127,7 @@ export default function FilesUpload() {
// 更新处理步骤状态
const updateProcessingSteps = (status: DocumentStatus) => {
console.log('更新处理步骤状态:', status);
// console.log('更新处理步骤状态:', status);
const updatedSteps = [...processingSteps];
@@ -1182,7 +1182,7 @@ export default function FilesUpload() {
const updateQueueFilesStatus = (updatedDocs: Document[]) => {
if (!updatedDocs.length) return;
console.log('更新队列中文件状态:', updatedDocs);
// console.log('更新队列中文件状态:', updatedDocs);
setQueueFiles(prevFiles => {
// 创建文件ID到状态的映射
@@ -1273,18 +1273,18 @@ export default function FilesUpload() {
// 处理查看文件
const handleViewFile = async (record: Document) => {
try {
console.log('【调试-handleViewFile】开始处理查看文件,文件ID:', record.id);
// console.log('【调试-handleViewFile】开始处理查看文件,文件ID:', record.id);
// 检查audit_status是否为0,如果是则更新为2
if (record.audit_status === 0 || record.audit_status === null) {
try {
console.log('【调试-handleViewFile】更新文件审核状态,文件ID:', record.id);
// console.log('【调试-handleViewFile】更新文件审核状态,文件ID:', record.id);
const response = await updateDocumentAuditStatus(record.id.toString(), 2);
if (response.error) {
console.error('【调试-handleViewFile】更新文件审核状态失败:', response.error);
toastService.error('更新文件审核状态失败:' + (response.error || '未知错误'));
} else {
console.log('【调试-handleViewFile】更新文件审核状态成功');
// console.log('【调试-handleViewFile】更新文件审核状态成功');
}
} catch (error) {
@@ -1294,7 +1294,7 @@ export default function FilesUpload() {
}
}
console.log(`【调试-handleViewFile】准备导航到文件详情页,文件ID: ${record.id}`);
// console.log(`【调试-handleViewFile】准备导航到文件详情页,文件ID: ${record.id}`);
// 检查组件是否已卸载
if (!isMountedRef.current) {
@@ -1306,7 +1306,7 @@ export default function FilesUpload() {
setTimeout(() => {
try {
if (isMountedRef.current) {
console.log(`【调试-handleViewFile】执行导航,URL: /reviews?id=${record.id}&previousRoute=filesUpload`);
// console.log(`【调试-handleViewFile】执行导航,URL: /reviews?id=${record.id}&previousRoute=filesUpload`);
navigate(`/reviews?id=${record.id}&previousRoute=filesUpload`);
} else {
console.error('【调试-handleViewFile】组件已卸载,取消延迟导航');
+7 -7
View File
@@ -1,5 +1,5 @@
// import React from 'react';
import { type MetaFunction, type LoaderFunctionArgs, redirect } from "@remix-run/node";
import { type MetaFunction } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { Card } from "~/components/ui/Card";
import { Button } from "~/components/ui/Button";
@@ -43,7 +43,7 @@ export const meta: MetaFunction = () => {
// }
// 添加认证检查
export async function loader({ request }: LoaderFunctionArgs) {
export async function loader() {
// 检查用户登录状态
// const { isAuthenticated } = await getUserSession(request);
@@ -65,11 +65,11 @@ export async function loader({ request }: LoaderFunctionArgs) {
return Response.json({ error: responseDocuments.error }, { status: responseDocuments.status || 500 });
}
const recentFiles = responseDocuments.data?.documents || [];
console.log("recentFiles-------",recentFiles);
// console.log("recentFiles-------",recentFiles);
const homeData = await getHomeData();
console.log("homeData-------",homeData);
// console.log("homeData-------",homeData);
return Response.json({ homeData, recentFiles });
@@ -125,7 +125,7 @@ export default function Home() {
order: 'updated_at.desc'
};
console.log('定时获取最新文档数据...');
// console.log('定时获取最新文档数据...');
const responseDocuments = await getDocuments(documentSearchParams);
if (responseDocuments.error) {
@@ -138,7 +138,7 @@ export default function Home() {
// 检查数据是否有变化
if (JSON.stringify(newRecentFiles) !== JSON.stringify(recentFiles)) {
console.log('文档数据已更新,直接更新状态');
// console.log('文档数据已更新,直接更新状态');
// 直接更新状态,不需要刷新页面
setRecentFiles(newRecentFiles);
}
@@ -152,7 +152,7 @@ export default function Home() {
// 组件卸载时清除定时器
return () => {
console.log('清除文档数据自动更新定时器');
// console.log('清除文档数据自动更新定时器');
clearInterval(timerID);
};
}, []); // 不再依赖recentFiles,避免循环依赖
+27 -8
View File
@@ -1,8 +1,8 @@
import { useState } from "react";
import { Form, useActionData, useNavigation } from "@remix-run/react";
import { type MetaFunction, type ActionFunctionArgs, redirect, json, type LoaderFunctionArgs } from "@remix-run/node";
import { type MetaFunction, type ActionFunctionArgs, redirect, type LoaderFunctionArgs } from "@remix-run/node";
import styles from "~/styles/pages/login.css?url";
import { createUserSession, getUserSession, getSession } from "~/root";
import { createUserSession, getUserSession, getSession, type UserRole } from "~/root";
export const links = () => [
{ rel: "stylesheet", href: styles }
@@ -20,21 +20,24 @@ export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData();
const username = formData.get("username") as string;
const password = formData.get("password") as string;
const userRole = formData.get("userRole") as UserRole || 'common';
// 简单的登录验证,实际应用中应该进行真正的身份验证
if (!username || !password) {
return json({ error: "用户名和密码不能为空" });
return Response.json({ error: "用户名和密码不能为空" });
}
// 在实际应用中,这里应该是对用户名和密码的验证逻辑
// 简化起见,我们直接视为登录成功
// 获取session中存储的重定向URL,如果没有则默认到/home
// 获取session中存储的重定向URL,如果没有则默认到/
const session = await getSession(request);
const redirectTo = session.get("redirectTo") || "/home";
// 查看session中存储的redirectTo值
const redirectTo = session.get("redirectTo") || "/";
// console.log("登录后重定向到:", redirectTo);
// 创建登录会话并重定向
return createUserSession(true, redirectTo);
return createUserSession(true, userRole, redirectTo);
}
// 加载器,获取当前会话状态
@@ -43,7 +46,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
// 如果已登录,重定向到首页
if (isAuthenticated) {
return redirect("/home");
return redirect("/");
}
return Response.json({ isAuthenticated });
@@ -52,6 +55,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
export default function Login() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [userRole, setUserRole] = useState<UserRole>("common");
const actionData = useActionData<typeof action>();
const navigation = useNavigation();
@@ -62,7 +66,7 @@ export default function Login() {
<div className="login-page">
<div className="login-container">
<div className="login-header">
<img src="/logo.png" alt="中国烟草" className="login-logo" />
{/* <img src="/logo.png" alt="中国烟草" className="login-logo" /> */}
<h1 className="login-title">AI合同及卷宗审核系统</h1>
</div>
@@ -101,6 +105,21 @@ export default function Login() {
/>
</div>
<div className="form-group">
<label htmlFor="userRole"></label>
<select
id="userRole"
name="userRole"
value={userRole}
onChange={(e) => setUserRole(e.target.value as UserRole)}
className="form-input"
required
>
<option value="common"></option>
{/* <option value="developer">开发者</option> */}
</select>
</div>
<button
type="submit"
className="login-button"
+2 -2
View File
@@ -54,7 +54,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
const page = parseInt(url.searchParams.get('page') || '1', 10);
const pageSize = parseInt(url.searchParams.get('pageSize') || '10', 10);
console.log('加载提示词模板参数:', { name, type, status, page, pageSize });
// console.log('加载提示词模板参数:', { name, type, status, page, pageSize });
// 从 API 获取数据
const result = await getPromptTemplates({
@@ -79,7 +79,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
);
}
console.log(`成功加载${result.data?.templates.length || 0}条提示词模板数据`);
// console.log(`成功加载${result.data?.templates.length || 0}条提示词模板数据`);
return Response.json({
templates: result.data?.templates || [],
+6 -6
View File
@@ -389,11 +389,11 @@ export default function ReviewDetails() {
return;
}
console.log('评查点状态更新成功:', {
id: reviewPointResultId,
result: boolResult,
message: message
});
// console.log('评查点状态更新成功:', {
// id: reviewPointResultId,
// result: boolResult,
// message: message
// });
// 更新本地状态
if (reviewData) {
@@ -451,7 +451,7 @@ export default function ReviewDetails() {
toastService.success('评查点状态已更新');
}
console.log("newReviewPoints",updatedReviewPoints);
// console.log("newReviewPoints",updatedReviewPoints);
// 如果是review操作才调用API刷新
// if (document && document.id && newStatus === 'review') {
+2 -2
View File
@@ -89,11 +89,11 @@ function mapApiToFrontend(apiGroup: ApiRuleGroup): RuleGroup {
// 数据加载器
export async function loader({ request }: LoaderFunctionArgs) {
console.log("rule-groups.new loader被调用,URL:", request.url);
// console.log("rule-groups.new loader被调用,URL:", request.url);
try {
const url = new URL(request.url);
const id = url.searchParams.get("id");
console.log("获取到的ID参数:", id);
// console.log("获取到的ID参数:", id);
// 获取一级分组列表 (用于选择父级分组)
const parentGroupsResponse = await getRuleGroups();
+21 -9
View File
@@ -50,6 +50,7 @@ import type { EvaluationPointGroup } from "~/models/evaluation_point_groups";
import { RuleContext } from "~/contexts/RuleContext";
import { postgrestGet, postgrestPost, postgrestPut } from "~/api/postgrest-client";
import { toastService } from '~/components/ui/Toast';
import type { UserRole } from '~/root';
export const meta: MetaFunction = () => {
return [
@@ -152,10 +153,13 @@ export default function RuleNew() {
const [isEditMode, setIsEditMode] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [instanceKey, setInstanceKey] = useState<string>('new');
const [userRole, setUserRole] = useState<UserRole>('common');
const [formData, setFormData] = useState<EvaluationPoint>({});
const [evaluationPointGroups, setEvaluationPointGroups] = useState<EvaluationPointGroup[]>([]);
// 检查用户是否为开发者角色
const isDeveloper = userRole === 'developer';
// 添加用于共享的字段数据状态
const [extractionFields, setExtractionFields] = useState<string[]>([]);
@@ -195,7 +199,7 @@ export default function RuleNew() {
* 重置表单数据到默认状态
*/
const resetFormData = useCallback(() => {
console.log("重置表单数据到默认状态");
// console.log("重置表单数据到默认状态");
setFormData({
name: '',
code: '',
@@ -250,7 +254,7 @@ export default function RuleNew() {
const fetchEvaluationPoint = useCallback(async (id: number) => {
try {
setIsLoading(true);
console.log(`获取评查点数据,ID: ${id}`);
// console.log(`获取评查点数据,ID: ${id}`);
// 使用 postgrestGet 替代直接调用 fetch
const postgrestParams = {
filter: {
@@ -268,7 +272,7 @@ export default function RuleNew() {
const jsonString = JSON.stringify(originalData);
const data = JSON.parse(jsonString);
console.log("数据已经过深拷贝处理,避免浏览器兼容性问题");
// console.log("数据已经过深拷贝处理,避免浏览器兼容性问题");
// 设置表单数据
setFormData(data);
@@ -311,7 +315,7 @@ export default function RuleNew() {
*/
const fetchEvaluationPointGroups = useCallback(async () => {
try {
console.log("获取评查点组数据");
// console.log("获取评查点组数据");
const response = await postgrestGet('evaluation_point_groups');
if (response.data && Array.isArray(response.data) && response.data.length > 0) {
@@ -325,7 +329,7 @@ export default function RuleNew() {
}, []);
const handleSave = async () => {
console.log("保存评查点", formData);
// console.log("保存评查点", formData);
// 验证必填字段
if (!formData.name?.trim()) {
@@ -405,7 +409,7 @@ export default function RuleNew() {
// 去重,确保不会有重复字段
const validFields = [...new Set(currentExtractionFields)];
console.log("当前有效的抽取字段:", validFields);
// console.log("当前有效的抽取字段:", validFields);
// 重要:这段代码解决了字段删除后,评查配置中仍保留已删除字段的问题
// 在保存前,我们会确保所有规则中引用的字段都是当前有效的抽取字段
@@ -548,8 +552,8 @@ export default function RuleNew() {
throw new Error(`数据大小超过限制 (${dataLength} > ${maxLength})`);
}
console.log("准备提交到API的数据(已经过深拷贝处理):", finalData);
console.log("JSON数据长度:", dataLength);
// console.log("准备提交到API的数据(已经过深拷贝处理):", finalData);
// console.log("JSON数据长度:", dataLength);
let response;
if (isEditMode) {
@@ -706,6 +710,12 @@ export default function RuleNew() {
const id = searchParams.get('id');
const mode = searchParams.get('mode');
// 从sessionStorage获取用户角色
if (typeof window !== 'undefined') {
const userRoleFromSession = sessionStorage.getItem('userRole') as UserRole || 'common';
setUserRole(userRoleFromSession);
}
// 编辑或复制模式下设置加载状态
if (id || mode === 'copy') {
setIsLoading(true);
@@ -737,6 +747,7 @@ export default function RuleNew() {
<PageHeader
title={isEditMode ? "编辑评查点" : "新增评查点"}
onSave={handleSave}
showSaveButton={isDeveloper}
/>
{/* 加载状态显示 */}
@@ -805,6 +816,7 @@ export default function RuleNew() {
onSave={handleSave}
onSaveDraft={handleSaveDraft}
isEditMode={isEditMode}
showButtons={isDeveloper}
/>
</div>
</RuleContext.Provider>
+39 -16
View File
@@ -22,6 +22,7 @@ import {
type RuleType as ApiRuleType,
type RuleGroup
} from '~/api/evaluation_points/rules';
import type { UserRole } from '~/root';
export const links = () => [
{ rel: "stylesheet", href: rulesStyles }
@@ -44,6 +45,7 @@ export type LoaderData = {
pageSize: number;
totalPages: number;
ruleTypes: ApiRuleType[]; // 添加评查点类型
userRole: UserRole; // 添加用户角色
};
// API返回的数据映射到前端模型
@@ -118,13 +120,19 @@ export async function loader({ request }: LoaderFunctionArgs) {
const apiRules = response.data?.rules || [];
const totalCount = response.data?.totalCount || 0;
const rules = apiRules.map((apiRule: ApiRule) => mapApiRuleToModel(apiRule));
// 从sessionStorage获取用户角色
const userRoleFromSession = typeof document !== 'undefined'
? sessionStorage.getItem('userRole') || 'common'
: 'common';
return Response.json({
rules,
totalCount,
currentPage: params.page,
pageSize: params.pageSize,
ruleTypes
ruleTypes,
userRole: userRoleFromSession as UserRole
}, {
headers: {
"Cache-Control": "max-age=60, s-maxage=180"
@@ -152,7 +160,7 @@ export async function action({ request }: LoaderFunctionArgs) {
try {
if (_action === 'delete') {
// 调用API删除评查点
console.log(`删除评查点 ${ruleId}`);
// console.log(`删除评查点 ${ruleId}`);
const deleteResponse = await deleteRule(ruleId as string);
@@ -178,12 +186,15 @@ const priorityLabels = {
export default function RulesIndex() {
const loaderData = useLoaderData<typeof loader>();
const { rules, totalCount, currentPage, pageSize } = loaderData;
const { rules, totalCount, currentPage, pageSize, userRole } = loaderData;
const ruleTypes = loaderData.ruleTypes || []; // 添加默认空数组避免undefined
const [searchParams, setSearchParams] = useSearchParams();
const navigate = useNavigate();
const fetcher = useFetcher<ActionResponse>();
// 检查用户是否为开发者角色
const isDeveloper = userRole === 'developer';
// 状态管理
const [ruleGroups, setRuleGroups] = useState<RuleGroup[]>([]);
const [loadingGroups, setLoadingGroups] = useState(false);
@@ -240,7 +251,7 @@ export default function RulesIndex() {
toastService.success(fetcher.data.message);
} else if (!fetcher.data.result) {
if(fetcher.data.message.includes("evaluation_results_evaluation_point_id_fkey")) {
toastService.error("对表evaluation_points进行更新或删除违反了表evaluation results上的外键约束evaluations results_evaluation _point_id_fkey”");
toastService.error('对表evaluation_points进行更新或删除违反了表evaluation results上的外键约束evaluations results_evaluation _point_id_fkey');
} else {
toastService.error(fetcher.data.message);
}
@@ -424,15 +435,25 @@ export default function RulesIndex() {
width: "10%",
render: (_: unknown, record: Rule) => (
<div className="operations-cell">
<Link to={`/rules-new?id=${record.id}`} className="operation-btn">
<i className="ri-edit-line"></i>
</Link>
<button className="operation-btn" onClick={() => handleCopy(record)}>
<i className="ri-file-copy-line"></i>
</button>
<button className="operation-btn operation-btn-danger" onClick={() => handleDeleteClick(record)}>
<i className="ri-delete-bin-line"></i>
</button>
{isDeveloper ? (
// 开发者可以看到编辑、复制、删除
<>
<Link to={`/rules-new?id=${record.id}`} className="operation-btn">
<i className="ri-edit-line"></i>
</Link>
<button className="operation-btn" onClick={() => handleCopy(record)}>
<i className="ri-file-copy-line"></i>
</button>
<button className="operation-btn operation-btn-danger" onClick={() => handleDeleteClick(record)}>
<i className="ri-delete-bin-line"></i>
</button>
</>
) : (
// 普通用户只能查看
<Link to={`/rules-new?id=${record.id}&mode=view`} className="operation-btn">
<i className="ri-eye-line"></i>
</Link>
)}
</div>
)
}
@@ -443,9 +464,11 @@ export default function RulesIndex() {
{/* 页面头部 */}
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-medium"></h2>
<Button type="primary" icon="ri-add-line" to="/rules-new" className="btn-add-rule">
</Button>
{isDeveloper && (
<Button type="primary" icon="ri-add-line" to="/rules-new" className="btn-add-rule">
</Button>
)}
</div>
{/* 筛选区域 */}
+2 -2
View File
@@ -169,7 +169,7 @@ export default function Documents() {
*/
function onDocumentLoadSuccess({ numPages }: DocumentLoadSuccess) {
setNumPages(numPages);
console.log("PDF加载成功,页数:", numPages);
// console.log("PDF加载成功,页数:", numPages);
}
/**
@@ -177,7 +177,7 @@ export default function Documents() {
* @param info 调试信息文本
*/
const addDebugInfo = (info: string) => {
console.log(info);
// console.log(info);
setDebugInfo(prev => [...prev, `${new Date().toISOString().split('T')[1].split('.')[0]}: ${info}`]);
};