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
+51 -31
View File
@@ -63,17 +63,17 @@ export async function loader({ request }: LoaderFunctionArgs) {
// 获取用户会话信息
const { getUserSession } = await import("~/api/login/auth.server");
const { userInfo, frontendJWT } = await getUserSession(request);
// 获取分页参数
const url = new URL(request.url);
const currentPage = parseInt(url.searchParams.get("page") || "1", 10);
const pageSize = parseInt(url.searchParams.get("pageSize") || "10", 10);
try {
// 获取文档类型列表
// 获取文档类型列表(服务端需要显式传递 token,客户端依赖 axios 拦截器)
const typesResponse = await getDocumentTypes({pageSize:500}, frontendJWT);
const documentTypes = typesResponse.data?.types || [];
// 返回初始空数据,客户端将根据 sessionStorage 中的 reviewType 加载实际数据
return Response.json({
files: [],
@@ -82,7 +82,6 @@ export async function loader({ request }: LoaderFunctionArgs) {
currentPage,
pageSize,
userInfo, // 传递用户信息到客户端
frontendJWT,
initialLoad: true
});
} catch (error) {
@@ -93,7 +92,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
export default function RulesFiles() {
const navigate = useNavigate();
const { files: initialFiles, documentTypes: allDocumentTypes, totalCount: initialTotal, currentPage, pageSize, userInfo, frontendJWT, result, message } = useLoaderData<typeof loader>();
const { files: initialFiles, documentTypes: allDocumentTypes, totalCount: initialTotal, currentPage, pageSize, userInfo, result, message } = useLoaderData<typeof loader>();
const [searchParams, setSearchParams] = useSearchParams();
const dateFrom = searchParams.get('dateFrom') || '';
const dateTo = searchParams.get('dateTo') || '';
@@ -141,12 +140,28 @@ export default function RulesFiles() {
}
}, [result, message]);
// 辅助函数:从 localStorage 获取用户ID
const getUserId = useCallback((): string | undefined => {
if (typeof window === 'undefined') return undefined;
const userInfoStr = localStorage.getItem('user_info');
if (!userInfoStr) return undefined;
try {
const userInfoData = JSON.parse(userInfoStr);
return userInfoData.user_id?.toString();
} catch (error) {
console.error('解析 localStorage 用户信息失败:', error);
return undefined;
}
}, []);
// 客户端数据请求
const fetchData = useCallback(async (params: Record<string, string>) => {
setIsLoading(true);
try {
// 构建搜索参数
// 构建搜索参数token 由 axios 拦截器自动从 localStorage 获取)
const searchParams: DocumentSearchParams = {
fileType: params.fileType || undefined,
reviewStatus: params.reviewStatus || undefined,
@@ -157,7 +172,7 @@ export default function RulesFiles() {
page: parseInt(params.page || "1", 10),
pageSize: parseInt(params.pageSize || "10", 10)
};
// 根据 reviewType 添加类型过滤
if (reviewType === 'contract') {
searchParams.fileType = 'contract';
@@ -165,21 +180,24 @@ export default function RulesFiles() {
// 在 API 层处理 type_id 为 2 或 3 的过滤
searchParams.fileType = 'record';
}
// 如果用户手动选择了文件类型,优先使用用户选择的
if (params.fileType) {
searchParams.fileType = params.fileType;
}
// 从loader data中获取用户ID
const userId = userInfo?.user_id?.toString();
// 获取文件列表
const filesResponse = await getReviewFiles({...searchParams, token: frontendJWT}, null, userId);
// 从 localStorage 获取用户ID(与 token 管理保持一致)
const userId = getUserId();
if (!userId) {
throw new Error('用户身份验证失败,无法获取评查文件列表');
}
// 获取文件列表(token 由 axios 拦截器自动添加)
const filesResponse = await getReviewFiles(searchParams, null, userId);
if (filesResponse.error) {
throw new Error(filesResponse.error);
}
setFiles(filesResponse.data?.files || []);
setTotalCount(filesResponse.data?.total || 0);
} catch (error) {
@@ -188,7 +206,7 @@ export default function RulesFiles() {
} finally {
setIsLoading(false);
}
}, [reviewType]);
}, [reviewType, getUserId]); // 使用 getUserId 辅助函数
// 在组件挂载时从 sessionStorage 获取 reviewType 并加载数据
useEffect(() => {
@@ -234,17 +252,19 @@ export default function RulesFiles() {
if (currentParams.fileType) {
apiSearchParams.fileType = currentParams.fileType;
}
// 设置加载状态
setIsLoading(true);
// 从loader data中获取用户ID
const userId = userInfo?.user_id?.toString();
// 添加 token 参数到 apiSearchParams
apiSearchParams.token = frontendJWT;
// 从 localStorage 获取用户ID
const userId = getUserId();
if (!userId) {
toastService.error('用户身份验证失败,无法获取评查文件列表');
setIsLoading(false);
return;
}
// 获取文件列表
// 获取文件列表token 由 axios 拦截器自动添加)
getReviewFiles(apiSearchParams, null, userId)
.then(filesResponse => {
if (filesResponse.error) {
@@ -331,14 +351,15 @@ export default function RulesFiles() {
// 检查audit_status是否为0,如果是则更新为2
if (auditStatus === 0 || auditStatus === null) {
try {
// 从loader data中获取用户ID
const userId = userInfo?.user_id?.toString();
// 从 localStorage 获取用户ID
const userId = getUserId();
if (!userId) {
toastService.error('用户身份验证失败');
return;
}
const response = await updateDocumentAuditStatus(fileId, 2, userId, frontendJWT);
// token 由 axios 拦截器自动添加
const response = await updateDocumentAuditStatus(fileId, 2, userId);
if (response.error) {
throw new Error(response.error);
}
@@ -348,7 +369,7 @@ export default function RulesFiles() {
return;
}
}
// 导航到评查详情页
// 在离开当前页前保存当前查询参数,返回时可恢复
if (typeof window !== 'undefined') {
@@ -520,8 +541,7 @@ export default function RulesFiles() {
attachmentFiles,
attachmentMergeMode,
true,
attachmentRemark || undefined,
frontendJWT as string | undefined
attachmentRemark || undefined
);
if (result.error) {
throw new Error(result.error);