fix: restore reviewsTest detail rendering

This commit is contained in:
wren
2026-05-06 10:01:21 +08:00
parent b36e102aa0
commit c3ef4dcefc
+70 -51
View File
@@ -155,6 +155,37 @@ interface ReviewData {
aiAnalysis: AnalysisData;
}
function buildReviewData(document: any, reviewPoints: ReviewPoint[], statistics: Statistics, reviewInfo: ReviewInfo): ReviewData | null {
if (!document) {
return null;
}
const mockData = getMockReviewData();
const typeValue = document.type ?? document.type_id;
return {
fileInfo: {
fileName: document.name || "未知文件名",
path: document.path || "未知路径",
contractNumber: document.documentNumber || document.document_number || "未知编号",
fileSize: document.size ? formatFileSize(document.size) : document.file_size ? formatFileSize(document.file_size) : "未知大小",
fileFormat: document.fileType ? document.fileType.toUpperCase() : "未知格式",
pageCount: document.pageCount || document.page_count || 0,
uploadTime: document.uploadTime || document.created_at || "未知时间",
uploadUser: document.uploadUser || "未知用户",
auditStatus: document.auditStatus || 0,
legalBasis: document.legalBasis || {},
fileType: typeValue !== undefined && typeValue !== null ? String(typeValue) : ""
},
contractInfo: mockData.contractInfo,
reviewInfo,
statistics,
fileContent: mockData.fileContent,
reviewPoints,
aiAnalysis: mockData.aiAnalysis,
};
}
export const meta: MetaFunction = () => {
return [
@@ -374,13 +405,32 @@ export async function action({ request }: ActionFunctionArgs) {
export default function ReviewDetails() {
const navigate = useNavigate();
const loaderData = useLoaderData<typeof loader>();
const normalizedLoaderData =
loaderData &&
typeof loaderData === 'object' &&
'reviewPoints' in loaderData &&
loaderData.reviewPoints &&
typeof loaderData.reviewPoints === 'object' &&
'data' in loaderData.reviewPoints &&
'document' in loaderData.reviewPoints
? {
...loaderData,
document: (loaderData.reviewPoints as any).document,
reviewPoints: (loaderData.reviewPoints as any).data,
reviewInfo: (loaderData.reviewPoints as any).reviewInfo,
statistics: (loaderData.reviewPoints as any).stats,
comparison_document: (loaderData.reviewPoints as any).comparison_document,
scoring_proposals: (loaderData.reviewPoints as any).scoring_proposals ?? [],
}
: loaderData;
const fetcher = useFetcher();
const { document, reviewPoints, statistics, reviewInfo, comparison_document, frontendJWT } = loaderData;
const { document, reviewPoints, statistics, reviewInfo, comparison_document, frontendJWT } = normalizedLoaderData as any;
const fallbackReviewData = buildReviewData(document, reviewPoints, statistics, reviewInfo);
const [isLoading, setIsLoading] = useState(false); // 已经通过loader加载了数据,不需要再显示加载状态
const [rightActiveTab, setRightActiveTab] = useState<'result' | 'fields' | 'info'>('result');
const [reviewData, setReviewData] = useState<ReviewData | null>(null);
const [reviewData, setReviewData] = useState<ReviewData | null>(fallbackReviewData);
const [activeReviewPointResultId, setActiveReviewPointResultId] = useState<string | null>(null);
const [targetPage, setTargetPage] = useState<number | undefined>(undefined);
const [charPositions, setCharPositions] = useState<Array<{ box: number[][], char: string, score: number }> | undefined>(undefined);
@@ -461,44 +511,13 @@ export default function ReviewDetails() {
}
}, [document?.id]);
// 模拟获取评查数据
// 使用 loader 数据同步本地评查页状态,避免首屏空白。
useEffect(() => {
if (!document) return;
// 构建文件信息对象
const fileInfo = {
fileName: document.name || "未知文件名",
path: document.path || "未知路径",
contractNumber: document.documentNumber || document.document_number || "未知编号",
fileSize: document.size ? formatFileSize(document.size) : document.file_size ? formatFileSize(document.file_size) : "未知大小",
// 文件格式类型
fileFormat: document.fileType ? document.fileType.toUpperCase() : "未知格式",
pageCount: document.pageCount || document.page_count || 0,
uploadTime: document.uploadTime || document.created_at || "未知时间",
uploadUser: document.uploadUser || "未知用户",
auditStatus: document.auditStatus || 0,
legalBasis: document.legalBasis || {},
// 文件类型(1:合同,2:卷宗。。。)
fileType: document.type || document.type_id ? document.type_id.toString() : ''
};
// 创建包含真实文档数据的评查数据对象
const reviewDataObj: ReviewData = {
// 使用真实文件信息
fileInfo: fileInfo,
// 其他字段暂时使用默认值
contractInfo: getMockReviewData().contractInfo,
reviewInfo: reviewInfo,
statistics: statistics,
fileContent: getMockReviewData().fileContent,
reviewPoints: reviewPoints,
aiAnalysis: getMockReviewData().aiAnalysis,
};
setReviewData(reviewDataObj);
setReviewData(buildReviewData(document, reviewPoints, statistics, reviewInfo));
setIsLoading(false);
}, [document, reviewPoints, statistics, reviewInfo]);
const effectiveReviewData = reviewData ?? fallbackReviewData;
const handleTabChange = (tabKey: 'result' | 'fields' | 'info') => {
setRightActiveTab(tabKey);
@@ -510,7 +529,7 @@ export default function ReviewDetails() {
setRightActiveTab('result');
// 查找评查点并尝试跳转到其页面
const point = reviewData?.reviewPoints.find(p => p.id === id);
const point = effectiveReviewData?.reviewPoints.find(p => p.id === id);
if (point) {
console.log('跳转到评查点页面:', point);
const page = getFirstPageFromPoint(point);
@@ -822,7 +841,7 @@ export default function ReviewDetails() {
};
// 获取当前激活的评查点对象
const activeReviewPoint = reviewData?.reviewPoints.find(p => p.id === activeReviewPointResultId) || null;
const activeReviewPoint = effectiveReviewData?.reviewPoints.find(p => p.id === activeReviewPointResultId) || null;
// ── 模板上传相关函数 ──
const handleOpenReuploadModal = () => {
@@ -892,7 +911,7 @@ export default function ReviewDetails() {
<button type="button" className="flex items-center gap-1 text-slate-600 hover:text-slate-900 text-[12.5px]" onClick={() => setShowComparison(false)}>
<i className="ri-arrow-left-line" />
</button>
<span className="font-medium text-sm text-slate-800 truncate">{reviewData?.fileInfo?.fileName}</span>
<span className="font-medium text-sm text-slate-800 truncate">{effectiveReviewData?.fileInfo?.fileName}</span>
</header>
<div className="flex-1 min-h-0 overflow-auto">
<Comparison comparison_document={comparison_document} />
@@ -908,14 +927,14 @@ export default function ReviewDetails() {
<div className="loading-spinner"></div>
<span className="ml-3">...</span>
</div>
) : reviewData ? (
) : effectiveReviewData ? (
<main className="flex-1 min-h-0 grid grid-cols-[22%,1fr,30%] p-2">
{/* 左栏:规则目录 */}
<RulesDirectory
reviewPoints={reviewData.reviewPoints}
statistics={reviewData.statistics}
reviewPoints={effectiveReviewData.reviewPoints}
statistics={effectiveReviewData.statistics}
activeReviewPointResultId={activeReviewPointResultId}
fileName={reviewData.fileInfo.fileName}
fileName={effectiveReviewData.fileInfo.fileName}
onRuleSelect={handleRuleSelect}
onBack={() => navigate(getReturnUrl())}
/>
@@ -929,10 +948,10 @@ export default function ReviewDetails() {
targetPage={targetPage}
charPositions={charPositions}
activeReviewPointResultId={activeReviewPointResultId}
reviewPoints={reviewData.reviewPoints}
reviewPoints={effectiveReviewData.reviewPoints}
highlightValue={highlightValue}
aiSuggestionReplace={aiSuggestionReplace}
userInfo={(loaderData as any)?.userInfo}
userInfo={(normalizedLoaderData as any)?.userInfo}
/>
) : (
<PdfPreviewTest
@@ -940,7 +959,7 @@ export default function ReviewDetails() {
targetPage={targetPage}
charPositions={charPositions}
activeReviewPointResultId={activeReviewPointResultId}
reviewPoints={reviewData.reviewPoints}
reviewPoints={effectiveReviewData.reviewPoints}
/>
)}
</section>
@@ -950,15 +969,15 @@ export default function ReviewDetails() {
activeTab={rightActiveTab}
onTabChange={handleTabChange}
activeReviewPoint={activeReviewPoint}
reviewPoints={reviewData.reviewPoints}
fileInfo={reviewData.fileInfo}
reviewInfo={reviewData.reviewInfo}
reviewPoints={effectiveReviewData.reviewPoints}
fileInfo={effectiveReviewData.fileInfo}
reviewInfo={effectiveReviewData.reviewInfo}
onReviewPointSelect={handleReviewPointSelect}
onStatusChange={handleReviewPointStatusChange}
onConfirmResults={handleConfirmResults}
onDownload={handleDownloadFile}
auditStatus={document?.auditStatus}
fileFormat={reviewData.fileInfo.fileFormat}
fileFormat={effectiveReviewData.fileInfo.fileFormat}
onUploadTemplate={handleOpenReuploadModal}
onComparison={() => setShowComparison(true)}
showComparisonButton={showComparisonButton}