feat: 1. 添加axios全局路由拦截进行自动添加请求jwt。 2.重新整理路由表。 3. 文档列表新增版本差异对比。 4.菜单路由可访问列表通过对接接口返回,添加全局路由检测。

5. 修改统一认证登录和管理员登录是通过接口形式进行,存储返回的accessToken。    6. 修改交叉评查的部分样式
This commit is contained in:
2025-11-18 11:06:24 +08:00
parent 8a50671c39
commit bfe39e45a9
53 changed files with 9503 additions and 2796 deletions
+253 -1
View File
@@ -93,6 +93,36 @@ export interface DocumentUI {
updatedAt?: string;
pageCount?: number;
ocrResult?: unknown;
// 版本管理相关字段
historyCount?: number; // 历史版本数量(不含当前版本)
previousIssues?: number | null; // 上一个版本的问题数量
isExpanded?: boolean; // 是否展开历史版本(前端状态)
historyVersions?: DocumentVersionUI[]; // 历史版本列表
}
/**
* 文档历史版本结构
*/
export interface DocumentVersionUI {
id: number;
name: string;
documentNumber: string;
type: string;
typeName: string;
size: number;
auditStatus: number;
fileStatus: string;
issues: number | null;
issuesDiff?: number; // 与上一个版本的问题数量差异(绝对值)
issuesDiffType?: 'increase' | 'decrease' | 'same'; // 差异类型
uploadTime: string;
fileType: string;
path: string;
isTest: boolean;
updatedAt?: string;
pageCount?: number;
ocrResult?: unknown;
versionNumber?: number; // 版本号(v2, v3, v4...
}
/**
@@ -419,6 +449,8 @@ export async function getDocumentWithNoUserId(id: string, frontendJWT?: string):
if (!id) {
return { error: '文档ID不能为空', status: 400 };
}
// console.log("get单个文档id", id)
const response = await postgrestGet<Document[]>(
'documents',
@@ -435,6 +467,7 @@ export async function getDocumentWithNoUserId(id: string, frontendJWT?: string):
return { error: response.error, status: response.status };
}
// console.log("respose", response)
const extractedData = extractApiData<Document[]>(response.data);
if (!extractedData || extractedData.length === 0) {
return { error: '文档不存在', status: 404 };
@@ -554,7 +587,7 @@ export async function updateDocument(id: string, document: Partial<DocumentUI> &
// 获取更新后的完整文档数据
const updatedResponse = await getDocument(id, userId, frontendJWT);
return updatedResponse;
return updatedResponse;
} catch (error) {
console.error('更新文档信息失败:', error);
return {
@@ -562,4 +595,223 @@ export async function updateDocument(id: string, document: Partial<DocumentUI> &
status: 500
};
}
}
/**
* 获取文档列表(带版本信息)- 使用 RPC 函数
* @param searchParams 搜索参数
* @returns 文档列表和总数
*/
export async function getDocumentsWithVersionInfo(searchParams: DocumentSearchParams = {}): Promise<{
data?: { documents: DocumentUI[], total: number };
error?: string;
status?: number;
}> {
try {
const {
page = 1,
pageSize = 10,
name,
documentNumber,
documentType,
auditStatus,
fileStatus,
dateFrom,
dateTo,
reviewType,
userId,
token
} = searchParams;
// 确保userId必须存在
if (!userId) {
return { error: '用户身份验证失败,无法获取文档列表', status: 401 };
}
// 处理文档类型
let documentTypes: number[] | undefined;
if (documentType) {
documentTypes = [parseInt(documentType, 10)];
} else if (reviewType) {
if (reviewType === 'contract') {
documentTypes = [1];
} else if (reviewType === 'record') {
documentTypes = [2, 3, 155];
}
}
// 准备RPC调用参数
const rpcParams = {
p_user_id: parseInt(userId, 10),
p_page: page,
p_page_size: pageSize,
p_search_name: name || null,
p_search_document_number: documentNumber || null,
p_search_document_types: documentTypes || null,
p_search_audit_status: auditStatus !== undefined ? parseInt(auditStatus, 10) : null,
p_search_file_status: fileStatus || null,
p_search_date_from: dateFrom || null,
p_search_date_to: dateTo || null
};
// 并行执行获取数据和获取总数的请求
const [documentsResponse, countResponse] = await Promise.all([
postgrestPost<any[], unknown>('rpc/documents_get_latest_documents_with_version_info', rpcParams, token),
postgrestPost<number, unknown>('rpc/documents_count_latest_documents_with_filters', {
p_user_id: rpcParams.p_user_id,
p_search_name: rpcParams.p_search_name,
p_search_document_number: rpcParams.p_search_document_number,
p_search_document_types: rpcParams.p_search_document_types,
p_search_audit_status: rpcParams.p_search_audit_status,
p_search_file_status: rpcParams.p_search_file_status,
p_search_date_from: rpcParams.p_search_date_from,
p_search_date_to: rpcParams.p_search_date_to
}, token)
]);
// 处理获取文档列表的错误
if (documentsResponse.error || !documentsResponse.data) {
return { error: documentsResponse.error || '获取文档数据失败', status: documentsResponse.status || 500 };
}
// 处理获取总数的错误
if (countResponse.error || typeof countResponse.data !== 'number') {
console.error('获取文档总数失败:', countResponse.error);
}
const totalCount = typeof countResponse.data === 'number' ? countResponse.data : 0;
// 将RPC返回的数据转换为UI格式
const documents: DocumentUI[] = documentsResponse.data.map((doc: any) => ({
id: doc.id,
name: doc.name,
documentNumber: doc.document_number,
type: doc.type_id.toString(),
typeName: doc.type_name || '未知类型',
size: doc.file_size,
auditStatus: doc.audit_status ?? 0,
fileStatus: doc.status || '',
issues: doc.false_count ?? null,
uploadTime: formatDate(doc.updated_at),
fileType: getFileExtension(doc.name),
path: doc.path,
isTest: doc.is_test_document,
updatedAt: formatDate(doc.updated_at),
pageCount: doc.ocr_result?.__meta?.page_count || 0,
ocrResult: doc.ocr_result,
historyCount: doc.history_count || 0,
previousIssues: doc.previous_issues
}));
return {
data: {
documents,
total: totalCount
}
};
} catch (error) {
console.error('获取文档列表失败:', error);
return {
error: error instanceof Error ? error.message : '获取文档列表失败',
status: 500
};
}
}
/**
* 获取文档历史版本列表
* @param documentName 文档名称
* @param userId 用户ID
* @param excludeId 排除的文档ID(当前最新版本的ID)
* @param token JWT token
* @returns 历史版本列表
*/
export async function getDocumentHistory(
documentName: string,
userId: string,
excludeId: number,
token?: string
): Promise<{
data?: DocumentVersionUI[];
error?: string;
status?: number;
}> {
try {
if (!documentName) {
return { error: '文档名称不能为空', status: 400 };
}
if (!userId) {
return { error: '用户身份验证失败', status: 401 };
}
// 调用 RPC 函数获取历史版本
const response = await postgrestPost<any[], unknown>(
'rpc/documents_get_document_history',
{
p_document_name: documentName,
p_user_id: parseInt(userId, 10),
p_exclude_id: excludeId
},
token
);
if (response.error || !response.data) {
return { error: response.error || '获取历史版本失败', status: response.status || 500 };
}
const historyDocs = response.data;
// 转换为 UI 格式,并计算问题数量差异
const documents: DocumentVersionUI[] = historyDocs.map((doc: any, index: number) => {
// 计算与下一个版本(更早的版本)的问题数量差异
let issuesDiff: number | undefined;
let issuesDiffType: 'increase' | 'decrease' | 'same' | undefined;
if (index < historyDocs.length - 1) {
const olderDoc = historyDocs[index + 1];
if (doc.false_count != null && olderDoc.false_count != null) {
const diff = doc.false_count - olderDoc.false_count;
issuesDiff = Math.abs(diff);
if (diff > 0) {
issuesDiffType = 'increase';
} else if (diff < 0) {
issuesDiffType = 'decrease';
} else {
issuesDiffType = 'same';
}
}
}
return {
id: doc.id,
name: doc.name,
documentNumber: doc.document_number,
type: doc.type_id.toString(),
typeName: doc.type_name || '未知类型',
size: doc.file_size,
auditStatus: doc.audit_status ?? 0,
fileStatus: doc.status || '',
issues: doc.false_count ?? null,
issuesDiff,
issuesDiffType,
uploadTime: formatDate(doc.created_at),
fileType: getFileExtension(doc.name),
path: doc.path,
isTest: doc.is_test_document,
updatedAt: formatDate(doc.updated_at),
pageCount: doc.ocr_result?.__meta?.page_count || 0,
ocrResult: doc.ocr_result,
versionNumber: historyDocs.length - index
};
});
return { data: documents };
} catch (error) {
console.error('获取文档历史版本失败:', error);
return {
error: error instanceof Error ? error.message : '获取文档历史版本失败',
status: 500
};
}
}