diff --git a/app/api/cross-checking/cross-files.ts b/app/api/cross-checking/cross-files.ts
index 435e248..8218c50 100644
--- a/app/api/cross-checking/cross-files.ts
+++ b/app/api/cross-checking/cross-files.ts
@@ -84,6 +84,8 @@ export interface TaskDocument {
message: string;
}>;
final_score: number;
+ score_summary: string ;
+ score_percent?: number | null;
pass_count: number;
warning_count: number;
fail_count: number;
diff --git a/app/components/cross-checking/DocumentListModal.tsx b/app/components/cross-checking/DocumentListModal.tsx
index bc16f32..12bbe05 100644
--- a/app/components/cross-checking/DocumentListModal.tsx
+++ b/app/components/cross-checking/DocumentListModal.tsx
@@ -1,4 +1,3 @@
-
import { Modal } from '../ui/Modal';
import { Table } from '../ui/Table';
import { Button } from '../ui/Button';
@@ -91,47 +90,6 @@ export function DocumentListModal({
};
- // 渲染问题摘要
- const renderIssues = (file: TaskDocument) => {
- // 如果文件有问题信息
- if (file.issues && file.issues.length > 0) {
- // 最多显示2个问题
- const displayIssues = file.issues.slice(0, 2);
-
- return (
-
- {displayIssues.map((issue, index) => (
-
-
- {issue.message}
-
- ))}
-
- {file.issues.length > 2 && (
-
- 还有 {file.issues.length - 2} 个问题...
-
- )}
-
- );
- }
-
- // 如果没有问题信息,根据状态显示
- if (file.evaluations_status === 1) {
- return (
-
- 所有评查点均通过
-
- );
- }
-
- // 其他状态显示占位符
- return -
;
- };
// 获取文件大小的友好显示
const formatFileSize = (bytes: number) => {
@@ -252,12 +210,8 @@ export function DocumentListModal({
render: (_: unknown, file: TaskDocument) => (
{file.final_score ? (
- = 90 ? 'text-green-600' :
- file.final_score >= 70 ? 'text-yellow-600' :
- 'text-red-600'
- }`}>
- {file.final_score}
+
+ {file.score_summary}
) : (
-
@@ -265,18 +219,27 @@ export function DocumentListModal({
)
},
+ {
+ title: "评查分数百分化",
+ key: "scorePercent",
+ width: "10%",
+ render: (_: unknown, file: TaskDocument) => {
+ const value: number | null | undefined = file.score_percent as number | null | undefined;
+ if (value === null || value === undefined || Number.isNaN(value)) {
+ return -;
+ }
+ const numericValue = typeof value === 'string' ? Number(value) : value;
+ const normalized = numericValue <= 1 ? numericValue * 100 : numericValue;
+ const display = `${Number(normalized.toFixed(1))}%`;
+ return {display};
+ }
+ },
{
title: '审核状态',
key: 'auditStatus',
width: '8%',
render: (_: unknown, file: TaskDocument) => renderAuditStatus(file)
},
- {
- title: "问题摘要",
- key: "issues",
- width: "20%",
- render: (_: unknown, file: TaskDocument) => renderIssues(file)
- },
{
title: "操作",
key: "operation",
diff --git a/app/config/api-config.ts b/app/config/api-config.ts
index c800ac6..af96e69 100644
--- a/app/config/api-config.ts
+++ b/app/config/api-config.ts
@@ -73,9 +73,9 @@ const portConfigs: Record> = {
// 主要
// 梅州
'51703': {
- baseUrl: 'http://10.79.97.17:8000',
- documentUrl: 'http://10.79.97.17:8000/docauditai/',
- uploadUrl: 'http://10.79.97.17:8000/admin/documents'
+ baseUrl: 'http://172.16.0.55:8000',
+ documentUrl: 'http://172.16.0.55:8000/docauditai/',
+ uploadUrl: 'http://172.16.0.55:8000/admin/documents'
},
diff --git a/app/routes/callback.tsx b/app/routes/callback.tsx
index 90066e5..f1dfee7 100644
--- a/app/routes/callback.tsx
+++ b/app/routes/callback.tsx
@@ -1,11 +1,10 @@
import { type LoaderFunctionArgs, redirect } from "@remix-run/node";
-import { OAuthClient } from "~/api/login/oauth-client";
-import { OAUTH_CONFIG } from "~/config/api-config";
import { createUserSession, saveUserInfo } from "~/api/login/auth.server";
import { JWTUtils, type UserInfoForJWT } from "~/utils/jwt";
export async function loader({ request }: LoaderFunctionArgs) {
const url = new URL(request.url);
+ const origin = url.origin; // 获取请求的源 (e.g., "http://10.79.97.17:51703")
const code = url.searchParams.get("code");
const state = url.searchParams.get("state");
const error = url.searchParams.get("error");
@@ -42,28 +41,56 @@ export async function loader({ request }: LoaderFunctionArgs) {
try {
console.log("🔧 开始处理OAuth2.0回调");
- // 创建OAuth客户端
- const oauthClient = new OAuthClient(OAUTH_CONFIG);
- console.log("✅ OAuth客户端创建成功");
+ // --- 修改开始: 不再直接调用OAuthClient,而是通过内部代理API ---
- // 获取访问令牌
- console.log("🔧 开始获取访问令牌...");
- const tokenResponse = await oauthClient.getAccessToken(code);
- if (!tokenResponse) {
- console.error("❌ 获取访问令牌失败");
- return redirect("/login?error=token_error");
- }
- console.log("✅ 访问令牌获取成功");
+ // 获取访问令牌 (通过代理)
+ console.log(`🔧 [Callback] 开始通过内部代理获取访问令牌... (目标: ${origin}/api/oauth/token)`);
+ const proxyResponse = await fetch(`${origin}/api/oauth/token`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ code }),
+ });
- // 获取用户信息
- const userInfo = await oauthClient.getUserInfo(tokenResponse.access_token);
- if (!userInfo || !userInfo.success) {
- console.error("获取用户信息失败:", userInfo);
- return redirect("/login?error=userinfo_error");
+ const tokenResponse = await proxyResponse.json();
+
+ if (!proxyResponse.ok || !tokenResponse.success) {
+ console.error("❌ [Callback] 通过内部代理获取访问令牌失败:", tokenResponse);
+ return redirect("/login?error=token_proxy_error");
}
+
+ // --- 修改结束 ---
+
+ console.log("✅ [Callback] 访问令牌获取成功");
+
+ // --- 修改开始: 通过内部代理获取用户信息 ---
+ console.log(`🔧 [Callback] 开始通过内部代理获取用户信息... (目标: ${origin}/api/oauth/userinfo)`);
+ const userInfoProxyResponse = await fetch(`${origin}/api/oauth/userinfo`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ accessToken: tokenResponse.access_token }),
+ });
+
+ const userInfoResponse = await userInfoProxyResponse.json();
+
+ if (!userInfoProxyResponse.ok || !userInfoResponse.success) {
+ console.error("❌ [Callback] 通过内部代理获取用户信息失败:", userInfoResponse);
+ return redirect("/login?error=userinfo_proxy_error");
+ }
+
+ // 将代理返回的用户信息包装成与原有一致的结构
+ const userInfo = {
+ success: true,
+ data: userInfoResponse.data,
+ };
+ // --- 修改结束 ---
+
+ console.log("✅ [Callback] 用户信息获取成功");
// TODO 根据用户信息判断用户角色,这里可以根据实际业务逻辑调整 暂定都是common
- // const userRole = userInfo.data.username === "admin" ? "developer" : "common";
const userRole = "common";
// 获取重定向URL
@@ -91,7 +118,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
ou_id: savedUserData.ou_id,
ou_name: savedUserData.ou_name,
is_leader: savedUserData.is_leader,
- user_role: userRole
+ user_role: userRole as 'common' | 'developer'
};
const frontendJWT = JWTUtils.generateJWT(jwtUserInfo, tokenResponse.expires_in);
diff --git a/app/routes/cross-checking._index.tsx b/app/routes/cross-checking._index.tsx
index 81150b5..f7ee4d8 100644
--- a/app/routes/cross-checking._index.tsx
+++ b/app/routes/cross-checking._index.tsx
@@ -172,7 +172,7 @@ export async function action({ request }: ActionFunctionArgs) {
}, { status: 500 });
}
- // console.log('用户任务详情返回:', response.data);
+ console.log('用户任务详情返回:', response.data);
return Response.json({
success: true,
data: response.data
diff --git a/app/routes/documents._index.tsx b/app/routes/documents._index.tsx
index 1e0abc3..21960c9 100644
--- a/app/routes/documents._index.tsx
+++ b/app/routes/documents._index.tsx
@@ -192,6 +192,26 @@ export default function DocumentsIndex() {
// 添加一个状态来跟踪是否执行了删除操作
const [isDeleting, setIsDeleting] = useState(false);
+ // 查询参数记忆 key 与保存/恢复方法
+ const SEARCH_PARAMS_STORAGE_KEY = 'documents.searchParams';
+ const persistSearchParams = (params: URLSearchParams) => {
+ if (typeof window !== 'undefined') {
+ sessionStorage.setItem(SEARCH_PARAMS_STORAGE_KEY, params.toString());
+ }
+ };
+
+ // 首次进入且 URL 无任何查询参数时,尝试从 sessionStorage 恢复
+ useEffect(() => {
+ if (typeof window === 'undefined') return;
+ const hasAnyParam = Array.from(searchParams.keys()).length > 0;
+ const stored = sessionStorage.getItem(SEARCH_PARAMS_STORAGE_KEY);
+ if (!hasAnyParam && stored) {
+ setSearchParams(new URLSearchParams(stored));
+ }
+ // 仅初始化检查一次
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
// 从URL获取当前筛选条件
const search = searchParams.get("search") || "";
const documentType = searchParams.get("documentType") || "";
@@ -202,7 +222,7 @@ export default function DocumentsIndex() {
const dateTo = searchParams.get("dateTo") || "";
const currentPage = parseInt(searchParams.get("page") || "1", 10);
const pageSize = parseInt(searchParams.get("pageSize") || "10", 10);
-
+
// 客户端数据请求
const fetchData = useCallback(async (storedReviewType: string) => {
setIsLoadingData(true);
@@ -323,15 +343,19 @@ export default function DocumentsIndex() {
// 分页处理函数
const handlePageChange = (page: number) => {
- searchParams.set("page", page.toString());
- setSearchParams(searchParams);
+ const params = new URLSearchParams(searchParams);
+ params.set("page", page.toString());
+ persistSearchParams(params);
+ setSearchParams(params);
};
// 每页条数变更处理函数
const handlePageSizeChange = (size: number) => {
- searchParams.set("pageSize", size.toString());
- searchParams.set("page", "1"); // 重置到第一页
- setSearchParams(searchParams);
+ const params = new URLSearchParams(searchParams);
+ params.set("pageSize", size.toString());
+ params.set("page", "1"); // 重置到第一页
+ persistSearchParams(params);
+ setSearchParams(params);
};
// 处理文档名称搜索
@@ -343,6 +367,7 @@ export default function DocumentsIndex() {
params.delete("search");
}
params.set("page", "1"); // 重置页码
+ persistSearchParams(params);
setSearchParams(params);
};
@@ -355,6 +380,7 @@ export default function DocumentsIndex() {
params.delete("documentNumber");
}
params.set("page", "1"); // 重置页码
+ persistSearchParams(params);
setSearchParams(params);
};
@@ -367,6 +393,7 @@ export default function DocumentsIndex() {
params.delete("documentType");
}
params.set("page", "1"); // 重置页码
+ persistSearchParams(params);
setSearchParams(params);
};
@@ -379,6 +406,7 @@ export default function DocumentsIndex() {
params.delete("auditStatus");
}
params.set("page", "1"); // 重置页码
+ persistSearchParams(params);
setSearchParams(params);
};
@@ -391,6 +419,7 @@ export default function DocumentsIndex() {
params.delete(field);
}
params.set("page", "1"); // 重置页码
+ persistSearchParams(params);
setSearchParams(params);
};
@@ -419,7 +448,10 @@ export default function DocumentsIndex() {
resetInput('input[name="dateFrom"]');
resetInput('input[name="dateTo"]');
- // 重置URL参数
+ // 重置URL参数并清除保存
+ if (typeof window !== 'undefined') {
+ sessionStorage.removeItem(SEARCH_PARAMS_STORAGE_KEY);
+ }
setSearchParams(new URLSearchParams({
page: "1",
pageSize: pageSize.toString()
@@ -681,8 +713,10 @@ export default function DocumentsIndex() {
return;
}
}
- // console.log('更新成功,开始跳转')
- // 导航到评查详情页
+ // 导航到评查详情页前保存查询参数
+ if (typeof window !== 'undefined') {
+ sessionStorage.setItem(SEARCH_PARAMS_STORAGE_KEY, searchParams.toString());
+ }
navigate(`/reviews?id=${fileId}&previousRoute=documents`);
};
diff --git a/app/routes/rules-files.tsx b/app/routes/rules-files.tsx
index a8f525f..dd70ca6 100644
--- a/app/routes/rules-files.tsx
+++ b/app/routes/rules-files.tsx
@@ -102,6 +102,27 @@ export default function RulesFiles() {
const [isLoading, setIsLoading] = useState(true);
const [reviewType, setReviewType] = useState(null);
+ // 保存/恢复 查询参数 的 sessionStorage key
+ const SEARCH_PARAMS_STORAGE_KEY = 'rulesFiles.searchParams';
+
+ const persistSearchParams = useCallback((params: URLSearchParams) => {
+ if (typeof window !== 'undefined') {
+ sessionStorage.setItem(SEARCH_PARAMS_STORAGE_KEY, params.toString());
+ }
+ }, []);
+
+ // 首次进入列表页且 URL 无查询参数时,尝试恢复上次保存的参数
+ useEffect(() => {
+ if (typeof window === 'undefined') return;
+ const hasAnyParam = Array.from(searchParams.keys()).length > 0;
+ const stored = sessionStorage.getItem(SEARCH_PARAMS_STORAGE_KEY);
+ if (!hasAnyParam && stored) {
+ setSearchParams(new URLSearchParams(stored));
+ }
+ // 仅在初始渲染时检查
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
// 处理初始加载数据loader的错误
useEffect(() => {
if(result === false && message) {
@@ -254,6 +275,7 @@ export default function RulesFiles() {
// 切换筛选条件时,重置到第一页
newParams.set('page', '1');
+ persistSearchParams(newParams);
setSearchParams(newParams);
};
@@ -269,6 +291,7 @@ export default function RulesFiles() {
// 搜索时,重置到第一页
newParams.set('page', '1');
+ persistSearchParams(newParams);
setSearchParams(newParams);
};
@@ -276,6 +299,7 @@ export default function RulesFiles() {
const handlePageChange = (page: number) => {
const newParams = new URLSearchParams(searchParams);
newParams.set('page', page.toString());
+ persistSearchParams(newParams);
setSearchParams(newParams);
};
@@ -284,6 +308,7 @@ export default function RulesFiles() {
const newParams = new URLSearchParams(searchParams);
newParams.set('pageSize', size.toString());
newParams.set('page', '1'); // 改变每页条数时重置为第一页
+ persistSearchParams(newParams);
setSearchParams(newParams);
};
@@ -311,6 +336,10 @@ export default function RulesFiles() {
}
// 导航到评查详情页
+ // 在离开当前页前保存当前查询参数,返回时可恢复
+ if (typeof window !== 'undefined') {
+ sessionStorage.setItem(SEARCH_PARAMS_STORAGE_KEY, searchParams.toString());
+ }
navigate(`/reviews?id=${fileId}&previousRoute=rulesFiles`);
};
@@ -412,6 +441,9 @@ export default function RulesFiles() {
if(searchInput) {
(searchInput as HTMLInputElement).value = '';
}
+ if (typeof window !== 'undefined') {
+ sessionStorage.removeItem(SEARCH_PARAMS_STORAGE_KEY);
+ }
setSearchParams(newParams);
};
diff --git a/app/routes/rules._index.tsx b/app/routes/rules._index.tsx
index a936ad2..54282c0 100644
--- a/app/routes/rules._index.tsx
+++ b/app/routes/rules._index.tsx
@@ -188,6 +188,26 @@ export default function RulesIndex() {
// 添加一个状态来跟踪是否执行了删除操作
const [isDeleting, setIsDeleting] = useState(false);
+ // 查询参数记忆 key 与保存/恢复
+ const SEARCH_PARAMS_STORAGE_KEY = 'rules.searchParams';
+ const persistSearchParams = (params: URLSearchParams) => {
+ if (typeof window !== 'undefined') {
+ sessionStorage.setItem(SEARCH_PARAMS_STORAGE_KEY, params.toString());
+ }
+ };
+
+ // 首次进入页且 URL 无参数时尝试恢复
+ useEffect(() => {
+ if (typeof window === 'undefined') return;
+ const hasAnyParam = Array.from(searchParams.keys()).length > 0;
+ const stored = sessionStorage.getItem(SEARCH_PARAMS_STORAGE_KEY);
+ if (!hasAnyParam && stored) {
+ setSearchParams(new URLSearchParams(stored));
+ }
+ // 仅初始化检查一次
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
// 获取当前的ruleType值
const ruleTypeParam = searchParams.get('ruleType');
@@ -416,7 +436,7 @@ export default function RulesIndex() {
// 切换筛选条件时,重置到第一页
newParams.set('page', '1');
-
+ persistSearchParams(newParams);
setSearchParams(newParams);
};
@@ -431,7 +451,7 @@ export default function RulesIndex() {
// 搜索时,重置到第一页
newParams.set('page', '1');
-
+ persistSearchParams(newParams);
setSearchParams(newParams);
};
@@ -463,6 +483,7 @@ export default function RulesIndex() {
const handlePageChange = (page: number) => {
const newParams = new URLSearchParams(searchParams);
newParams.set('page', page.toString());
+ persistSearchParams(newParams);
setSearchParams(newParams);
};
@@ -471,6 +492,7 @@ export default function RulesIndex() {
const newParams = new URLSearchParams(searchParams);
newParams.set('pageSize', size.toString());
newParams.set('page', '1'); // 更改每页条数时,重置到第一页
+ persistSearchParams(newParams);
setSearchParams(newParams);
};
@@ -482,6 +504,9 @@ export default function RulesIndex() {
}
// 保留reviewType的过滤条件,只重置其他条件
const newParams = new URLSearchParams();
+ if (typeof window !== 'undefined') {
+ sessionStorage.removeItem(SEARCH_PARAMS_STORAGE_KEY);
+ }
setSearchParams(newParams);
};