添加合同和卷宗数据隔离
This commit is contained in:
+160
-77
@@ -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`}>
|
||||
|
||||
Reference in New Issue
Block a user