添加合同和卷宗数据隔离

This commit is contained in:
2025-06-03 12:16:31 +08:00
parent b02978508d
commit 0397139ad8
20 changed files with 1190 additions and 437 deletions
+160 -77
View File
@@ -7,7 +7,7 @@ import { FileTag, links as fileTagLinks } from "~/components/ui/FileTag";
// import { FileTypeTag, links as fileTypeTagLinks } from "~/components/ui/FileTypeTag";
import { Tag } from "~/components/ui/Tag";
import homeStyles from "~/styles/pages/sys_overview.css?url";
import { getDocuments, type DocumentUI } from "~/api/files/documents";
import { getDocuments, type DocumentUI, type DocumentSearchParams } from "~/api/files/documents";
import { useState, useEffect } from "react";
import { getHomeData } from "~/api/home/home";
import dayjs from 'dayjs';
@@ -52,27 +52,20 @@ export async function loader() {
// }
try {
const documentSearchParams = {
page: 1,
pageSize: 10,
order: 'updated_at.desc'
};
// 获取最近文档数据
const responseDocuments = await getDocuments(documentSearchParams);
if (responseDocuments.error) {
console.error('获取最近文档数据失败', responseDocuments.error);
return Response.json({ error: responseDocuments.error }, { status: responseDocuments.status || 500 });
}
const recentFiles = responseDocuments.data?.documents || [];
// console.log("recentFiles-------",recentFiles);
const homeData = await getHomeData();
// console.log("homeData-------",homeData);
return Response.json({ homeData, recentFiles });
// 返回默认值,实际数据将在客户端根据 sessionStorage 加载
return Response.json({
homeData: {
todayPendingFiles: 0,
monthlyReviewedFiles: 0,
monthlyReviewGrowth: { value: 0, isUp: true },
monthlyPassRate: 0,
passRateGrowth: { value: 0, isUp: true },
issuesDetected: 0,
issuesGrowth: { value: 0, isUp: true }
},
recentFiles: [],
reviewType: null
});
} catch (error) {
// 错误处理
console.error('Failed to fetch dashboard data:', error);
@@ -84,13 +77,14 @@ export async function loader() {
}
export default function Home() {
const { homeData, recentFiles: initialRecentFiles } = useLoaderData<typeof loader>();
// 使用useState存储最近文档数据,初始值为loader加载的数据
const { homeData: initialHomeData, recentFiles: initialRecentFiles } = useLoaderData<typeof loader>();
const [recentFiles, setRecentFiles] = useState<DocumentUI[]>(initialRecentFiles || []);
const [homeData, setHomeData] = useState(initialHomeData);
const [currentDateTime, setCurrentDateTime] = useState({
date: '',
time: ''
});
const [isLoading, setIsLoading] = useState(true);
// 更新当前时间
useEffect(() => {
@@ -113,38 +107,132 @@ export default function Home() {
return () => clearInterval(timerID);
}, []);
// 在客户端挂载时,根据 sessionStorage 中的 reviewType 加载正确的数据
useEffect(() => {
const loadData = async () => {
try {
setIsLoading(true);
// 从 sessionStorage 获取 reviewType
const reviewType = sessionStorage.getItem('reviewType');
// 加载主页数据
const newHomeData = await getHomeData(reviewType || undefined);
setHomeData(newHomeData);
// 加载文档数据
const docs = await loadDocuments(reviewType);
setRecentFiles(docs);
setIsLoading(false);
} catch (error) {
console.error('加载数据失败:', error);
setIsLoading(false);
}
};
loadData();
}, []); // 仅在组件挂载时执行一次
// 加载文档数据的函数
const loadDocuments = async (reviewType: string | null) => {
try {
const documentSearchParams: DocumentSearchParams = {
page: 1,
pageSize: 10
};
// 根据 reviewType 添加过滤条件
if (reviewType === 'contract') {
documentSearchParams.documentType = '1';
const response = await getDocuments(documentSearchParams);
if (!response.error && response.data) {
return response.data.documents;
}
} else if (reviewType === 'record') {
// 获取类型 2 的文档
const response1 = await getDocuments({
...documentSearchParams,
documentType: '2'
});
// 获取类型 3 的文档
const response2 = await getDocuments({
...documentSearchParams,
documentType: '3'
});
if (!response1.error && !response2.error && response1.data && response2.data) {
// 合并文档并排序
const mergedDocs = [...response1.data.documents, ...response2.data.documents];
mergedDocs.sort((a, b) =>
new Date(b.updatedAt || '').getTime() - new Date(a.updatedAt || '').getTime()
);
// 限制数量
return mergedDocs.slice(0, documentSearchParams.pageSize);
}
} else {
// 没有特定类型,获取所有文档
const response = await getDocuments(documentSearchParams);
if (!response.error && response.data) {
return response.data.documents;
}
}
return []; // 默认返回空数组
} catch (error) {
console.error('加载文档数据失败:', error);
return [];
}
};
// 监听 sessionStorage 中 reviewType 的变化
useEffect(() => {
const handleStorageChange = async () => {
const currentReviewType = sessionStorage.getItem('reviewType');
const previousReviewType = sessionStorage.getItem('previousReviewType');
// 如果 reviewType 发生变化
if (currentReviewType !== previousReviewType) {
setIsLoading(true);
// 更新主页数据
const newHomeData = await getHomeData(currentReviewType || undefined);
setHomeData(newHomeData);
// 更新文档数据
const docs = await loadDocuments(currentReviewType);
setRecentFiles(docs);
// 保存当前 reviewType 为上一次的值,用于比较
sessionStorage.setItem('previousReviewType', currentReviewType || '');
setIsLoading(false);
}
};
// 设置初始的 previousReviewType
const initialReviewType = sessionStorage.getItem('reviewType');
sessionStorage.setItem('previousReviewType', initialReviewType || '');
// 设置定期检查
const checkInterval = setInterval(handleStorageChange, 1000);
return () => {
clearInterval(checkInterval);
};
}, []);
// 修改useEffect定时器,每10秒自动获取最近文档数据
// 按照定时器更新最近文档
useEffect(() => {
// 定义一个函数用于获取最新的文档数据
// 避免在加载状态下进行自动更新
if (isLoading) return;
const fetchLatestDocuments = async () => {
try {
const documentSearchParams = {
page: 1,
pageSize: 10,
order: 'updated_at.desc'
};
// console.log('定时获取最新文档数据...');
const responseDocuments = await getDocuments(documentSearchParams);
if (responseDocuments.error) {
console.error('获取最近文档数据失败', responseDocuments.error);
return;
}
// 获取新的文档数据
const newRecentFiles = responseDocuments.data?.documents || [];
// 检查数据是否有变化
if (JSON.stringify(newRecentFiles) !== JSON.stringify(recentFiles)) {
// console.log('文档数据已更新,直接更新状态');
// 直接更新状态,不需要刷新页面
setRecentFiles(newRecentFiles);
}
} catch (error) {
console.error('自动获取文档数据失败:', error);
}
const reviewType = sessionStorage.getItem('reviewType');
const docs = await loadDocuments(reviewType);
setRecentFiles(docs);
};
// 设置10秒的定时器
@@ -152,10 +240,9 @@ export default function Home() {
// 组件卸载时清除定时器
return () => {
// console.log('清除文档数据自动更新定时器');
clearInterval(timerID);
};
}, []); // 不再依赖recentFiles,避免循环依赖
}, [isLoading]); // 仅依赖 isLoading 状态
return (
<div className="dashboard-container">
@@ -188,24 +275,24 @@ export default function Home() {
value={homeData.todayPendingFiles}
icon="ri-inbox-line"
/>
<StatCard
title="本月已审核文件"
value={homeData.monthlyReviewedFiles}
icon="ri-file-search-line"
trend={{ value: homeData.monthlyReviewGrowth.value, isUp: homeData.monthlyReviewGrowth.isUp }}
/>
<StatCard
title="本月审核通过率"
value={homeData.monthlyPassRate}
icon="ri-percent-line"
trend={{ value: homeData.passRateGrowth.value, isUp: homeData.passRateGrowth.isUp }}
/>
<StatCard
title="本月问题检出数"
value={homeData.issuesDetected}
icon="ri-error-warning-line"
trend={{ value: homeData.issuesGrowth.value, isUp: homeData.issuesGrowth.isUp }}
/>
<StatCard
title="本月已审核文件"
value={homeData.monthlyReviewedFiles}
icon="ri-file-search-line"
trend={{ value: homeData.monthlyReviewGrowth.value, isUp: homeData.monthlyReviewGrowth.isUp }}
/>
<StatCard
title="本月审核通过率"
value={homeData.monthlyPassRate}
icon="ri-percent-line"
trend={{ value: homeData.passRateGrowth.value, isUp: homeData.passRateGrowth.isUp }}
/>
<StatCard
title="本月问题检出数"
value={homeData.issuesDetected}
icon="ri-error-warning-line"
trend={{ value: homeData.issuesGrowth.value, isUp: homeData.issuesGrowth.isUp }}
/>
</div>
</Card>
@@ -216,10 +303,6 @@ export default function Home() {
<ShortcutItem icon="ri-file-list-3-line" label="文档列表" to="/documents" />
<ShortcutItem icon="ri-list-check-3" label="评查点列表" to="/rules" />
<ShortcutItem icon="ri-folder-open-line" label="评查点分组" to="/rule-groups" />
{/* <ShortcutItem icon="ri-file-chart-line" label="评查详情" to="/reviews" /> */}
<ShortcutItem icon="ri-file-list-line" label="文档类型" to="/document-types" />
{/* <ShortcutItem icon="ri-settings-3-line" label="系统设置" to="/settings" /> */}
<ShortcutItem icon="ri-chat-1-line" label="提示词管理" to="/prompts" />
</div>
</Card>
@@ -257,7 +340,7 @@ export default function Home() {
{(() => {
const fileStatus = file.fileStatus || "-";
const status = fileProcessingStatusOptions.find(s => s.value === fileStatus) ||
fileProcessingStatusOptions[0];
fileProcessingStatusOptions[0];
const isSpinning = fileStatus !== "Processed";
return (
<div className={`inline-flex items-center px-2 py-1 rounded-full text-xs bg-${status.color}-100 text-${status.color}-800`}>