feat: 1. 重构交叉评查任务的文档列表的显示,对接接口查询当前任务的文档相关信息。

2.文档上传通过接口去查询是否存在同名的文件,做上传前拦截提示。
3.交叉评查的评查结果也同步添加企查查的企业信息查询模块。
4. 封装上传附件和上传模板的模态框的组件,在交叉评查的文档列表中引入显示。
5. 交叉评查的评查结果中关于合同类型的文档同步加入结构比对的功能。
This commit is contained in:
2025-12-13 07:18:37 +08:00
parent daa53289af
commit 1658bb1c6f
11 changed files with 3368 additions and 363 deletions
+84 -63
View File
@@ -18,14 +18,18 @@ import {
deleteCrossCheckingTask,
getCrossCheckingTaskDetail,
getCrossCheckingDocumentTypes,
getTaskDocumentsWithVersions,
type CrossCheckingTask,
type TaskDocument,
type CrossReviewDocumentWithVersion,
type CrossReviewDocumentListResponse,
type TaskListParams,
type DocumentType,
CrossCheckingTaskStatus,
CrossCheckingTaskType,
CrossCheckingDocType
} from '~/api/cross-checking/cross-files';
import { findIsProposer } from '~/api/cross-checking/cross-file-result';
export const links = () => [
{ rel: "stylesheet", href: crossCheckingStyles }
@@ -258,23 +262,28 @@ export default function CrossCheckingIndex() {
// 状态管理
const [isDeleting, setIsDeleting] = useState(false);
const [hasAutoOpened, setHasAutoOpened] = useState(false); // 标记是否已自动打开模态框
const [isProposer, setIsProposer] = useState<boolean>(false); // 是否是负责人
const [isProposerLoading, setIsProposerLoading] = useState<boolean>(false); // 负责人状态加载中
const [modalState, setModalState] = useState<{
isOpen: boolean;
title: string;
files: TaskDocument[];
documents: CrossReviewDocumentWithVersion[];
loading: boolean;
// 分页相关状态
currentPage: number;
pageSize: number;
total: number;
// 搜索关键词
keyword: string;
}>({
isOpen: false,
title: '',
files: [],
documents: [],
loading: false,
currentPage: 1,
pageSize: 10,
total: 0
total: 0,
keyword: ''
});
// 客户端调式日志
@@ -293,17 +302,29 @@ export default function CrossCheckingIndex() {
const handleViewResult = async (taskId: number, taskName: string) => {
// 存储任务信息用于分页
setCurrentTaskInfo({ taskId, taskName });
// 打开模态框
// 重置负责人状态
setIsProposer(false);
setIsProposerLoading(true);
// 打开模态框,同时设置标题
setModalState(prev => ({
...prev,
isOpen: true,
title: `${taskName} - 文档列表`,
currentPage: 1,
pageSize: 10
}));
// 加载第一页数据
await loadModalData(taskId, 1, 10);
// 并行加载:文档列表和负责人状态
const [, isProposerResult] = await Promise.all([
loadModalData(taskId, 1, 10, undefined, taskName),
findIsProposer(taskId, undefined, frontendJWT)
]);
// 设置负责人状态
setIsProposer(isProposerResult);
setIsProposerLoading(false);
};
// 关闭模态框
@@ -311,13 +332,17 @@ export default function CrossCheckingIndex() {
setModalState({
isOpen: false,
title: '',
files: [],
documents: [],
loading: false,
currentPage: 1,
pageSize: 10,
total: 0
total: 0,
keyword: ''
});
setCurrentTaskInfo(null);
// 重置负责人状态
setIsProposer(false);
setIsProposerLoading(false);
};
// 处理文档查看 - 导航到评查详情页
@@ -337,27 +362,48 @@ export default function CrossCheckingIndex() {
taskName: string;
} | null>(null);
// 加载分页数据
const loadModalData = async (taskId: number, page: number = 1, pageSize: number = 10) => {
// 加载分页数据(使用新版接口,支持版本归纳)
const loadModalData = async (taskId: number, page: number = 1, pageSize: number = 10, keyword?: string, taskName?: string) => {
try {
setModalState(prev => ({
...prev,
loading: true
loading: true,
currentPage: page,
pageSize: pageSize
}));
// 使用 fetcher 调用 action 来获取任务详情
const formData = new FormData();
formData.append('_action', 'getTaskDetail');
formData.append('taskId', taskId.toString());
formData.append('page', page.toString());
formData.append('pageSize', pageSize.toString());
// 直接调用新版 API(支持版本归纳)
const response = await getTaskDocumentsWithVersions({
taskId,
page,
pageSize,
keyword,
jwtToken: frontendJWT
});
if (!response.success || !response.data) {
throw new Error(response.error || '获取任务文档列表失败');
}
const { documents, total, page: returnedPage, page_size: returnedPageSize, total_pages } = response.data;
// 使用传入的 taskName 或 currentTaskInfo 中的 taskName
const displayTaskName = taskName || currentTaskInfo?.taskName || '';
setModalState(prev => ({
...prev,
loading: false,
title: displayTaskName ? `${displayTaskName} - 文档列表` : prev.title,
documents: documents || [],
total: total || 0,
currentPage: returnedPage || page,
pageSize: returnedPageSize || pageSize
}));
fetcher.submit(formData, { method: "POST" });
} catch (error) {
console.error('获取任务文档列表失败:', error);
toastService.error(`获取任务文档列表失败: ${error instanceof Error ? error.message : '未知错误'}`);
setModalState(prev => ({
...prev,
loading: false
@@ -368,14 +414,22 @@ export default function CrossCheckingIndex() {
// 处理模态框分页变化
const handleModalPageChange = (page: number) => {
if (currentTaskInfo) {
loadModalData(currentTaskInfo.taskId, page, modalState.pageSize);
loadModalData(currentTaskInfo.taskId, page, modalState.pageSize, modalState.keyword);
}
};
// 处理模态框每页大小变化
const handleModalPageSizeChange = (size: number) => {
if (currentTaskInfo) {
loadModalData(currentTaskInfo.taskId, 1, size);
loadModalData(currentTaskInfo.taskId, 1, size, modalState.keyword);
}
};
// 处理模态框搜索
const handleModalSearch = (keyword: string) => {
if (currentTaskInfo) {
setModalState(prev => ({ ...prev, keyword }));
loadModalData(currentTaskInfo.taskId, 1, modalState.pageSize, keyword);
}
};
@@ -561,44 +615,6 @@ export default function CrossCheckingIndex() {
}
}, [fetcher.data, fetcher.state, isDeleting]);
// 监听fetcher状态变化 - 获取任务详情
useEffect(() => {
if (fetcher.data && fetcher.state === 'idle' && !isDeleting && modalState.loading) {
const data = fetcher.data as {
success?: boolean;
data?: {
files: TaskDocument[];
total: number;
currentPage: number;
pageSize: number;
};
error?: string;
};
if (data.success && data.data) {
const { files, total, currentPage, pageSize: returnedPageSize } = data.data;
setModalState(prev => ({
...prev,
loading: false,
title: `${currentTaskInfo?.taskName || ''} - 文档列表`,
files: files || [],
total: total || 0,
currentPage: currentPage || prev.currentPage,
pageSize: returnedPageSize || prev.pageSize
}));
} else {
console.error('获取任务文档列表失败:', data.error);
toastService.error(`获取任务文档列表失败: ${data.error || '未知错误'}`);
setModalState(prev => ({
...prev,
loading: false
}));
}
}
}, [fetcher.data, fetcher.state, isDeleting, modalState.loading, currentTaskInfo?.taskId]);
// 定义表格列配置
const columns = [
{
@@ -849,7 +865,7 @@ export default function CrossCheckingIndex() {
isOpen={modalState.isOpen}
onClose={handleCloseModal}
title={modalState.title}
files={modalState.files}
documents={modalState.documents}
onViewFile={handleViewFile}
loading={modalState.loading}
currentPage={modalState.currentPage}
@@ -857,7 +873,12 @@ export default function CrossCheckingIndex() {
total={modalState.total}
onPageChange={handleModalPageChange}
onPageSizeChange={handleModalPageSizeChange}
onSearch={handleModalSearch}
taskId={currentTaskInfo?.taskId}
taskName={currentTaskInfo?.taskName}
frontendJWT={frontendJWT}
isProposer={isProposer}
isProposerLoading={isProposerLoading}
/>
</div>
);