优化客户端请求时候操作的页面不更新

This commit is contained in:
2025-06-06 10:21:14 +08:00
parent ce4e621741
commit 358e9ab745
10 changed files with 162 additions and 81 deletions
+19 -2
View File
@@ -175,6 +175,9 @@ export default function DocumentsIndex() {
const [filteredDocumentTypeOptions, setFilteredDocumentTypeOptions] = useState(loaderData.documentTypeOptions);
const dataCache = useRef<typeof loaderData | null>(null);
// 添加一个状态来跟踪是否执行了删除操作
const [isDeleting, setIsDeleting] = useState(false);
// 从URL获取当前筛选条件
const search = searchParams.get("search") || "";
const documentType = searchParams.get("documentType") || "";
@@ -283,14 +286,22 @@ export default function DocumentsIndex() {
// 使用useEffect监听fetcher状态变化并显示Toast
useEffect(() => {
if (fetcher.data && fetcher.state === 'idle') {
if (fetcher.data && fetcher.state === 'idle' && isDeleting) {
// 重置删除状态
setIsDeleting(false);
if (fetcher.data.result) {
toastService.success(fetcher.data.message);
// 删除成功后重新加载数据
if (reviewType) {
fetchData(reviewType);
}
} else if (fetcher.data.message) {
toastService.error(fetcher.data.message);
// 删除失败只显示错误信息,不刷新数据
}
}
}, [fetcher.data, fetcher.state]);
}, [fetcher.data, fetcher.state, fetchData, reviewType, isDeleting]);
// 分页处理函数
const handlePageChange = (page: number) => {
@@ -468,6 +479,9 @@ export default function DocumentsIndex() {
confirmText: "删除",
cancelText: "取消",
onConfirm: () => {
// 设置删除状态为true
setIsDeleting(true);
const form = new FormData();
form.append("_action", "delete");
form.append("id", id);
@@ -501,6 +515,9 @@ export default function DocumentsIndex() {
confirmText: "删除",
cancelText: "取消",
onConfirm: () => {
// 设置删除状态为true
setIsDeleting(true);
// 使用fetcher提交表单
const formData = new FormData();
formData.append('_action', 'batchDelete');
+6 -7
View File
@@ -1,5 +1,5 @@
import { useState } from "react";
import { useActionData } from "@remix-run/react";
import { useActionData, Form } from "@remix-run/react";
import { type MetaFunction, type ActionFunctionArgs, redirect, type LoaderFunctionArgs } from "@remix-run/node";
import styles from "~/styles/pages/login.css?url";
import { getUserSession, getSession, type UserRole, sessionStorage } from "~/root";
@@ -22,7 +22,7 @@ export async function action({ request }: ActionFunctionArgs) {
const password = formData.get("password") as string;
const userRole = formData.get("userRole") as UserRole || 'common';
console.log("userRole-----", userRole);
// console.log("userRole-----", userRole);
// 简单的登录验证,实际应用中应该进行真正的身份验证
if (!username || !password) {
@@ -39,7 +39,7 @@ export async function action({ request }: ActionFunctionArgs) {
const session = await getSession(request);
// 查看session中存储的redirectTo值
const redirectTo = session.get("redirectTo") || "/";
console.log("登录后重定向到:", redirectTo);
// console.log("登录后重定向到:", redirectTo);
// 创建会话cookie
const newSession = await sessionStorage.getSession();
@@ -47,7 +47,7 @@ export async function action({ request }: ActionFunctionArgs) {
newSession.set("userRole", userRole);
const cookie = await sessionStorage.commitSession(newSession);
console.log("设置cookie:", !!cookie);
// console.log("设置cookie:", !!cookie);
// 使用新方法进行重定向
return redirect(redirectTo, {
@@ -85,8 +85,7 @@ export default function Login() {
<div className="login-form-container">
<h2 className="login-subtitle"></h2>
<form
action="/login"
<Form
method="post"
className="login-form"
>
@@ -144,7 +143,7 @@ export default function Login() {
>
</button>
</form>
</Form>
</div>
<div className="login-footer">
+27 -5
View File
@@ -249,6 +249,28 @@ export default function RuleNew() {
setInstanceKey(`new_${Date.now()}`);
}, []);
/**
* 从API响应中提取数据
* @param responseData - API响应数据
* @returns 提取的数据或null
*/
function extractApiData<T>(responseData: unknown): T | null {
if (!responseData) return null;
// 格式1: { code: number, msg: string, data: T }
if (typeof responseData === 'object' && responseData !== null &&
'code' in responseData &&
'data' in responseData &&
(responseData as { data: unknown }).data) {
return (responseData as { data: T }).data;
}
// 格式2: 直接是数据对象
return responseData as T;
}
/**
* 获取评查点数据
* 编辑模式下从API获取指定ID的评查点数据
@@ -266,17 +288,17 @@ export default function RuleNew() {
};
const response = await postgrestGet('evaluation_points', postgrestParams);
if (response.data && Array.isArray(response.data) && response.data[0]) {
if (response.data) {
// 使用extractApiData从响应中提取数据
const evaluationPoints = extractApiData<EvaluationPoint[]>(response.data);
if (response.data.length > 0) {
if (evaluationPoints && Array.isArray(evaluationPoints) && evaluationPoints.length > 0) {
try {
// 使用JSON序列化和反序列化来进行深拷贝,避免浏览器差异
const originalData = response.data[0];
const originalData = evaluationPoints[0];
const jsonString = JSON.stringify(originalData);
const data = JSON.parse(jsonString);
// console.log("数据已经过深拷贝处理,避免浏览器兼容性问题");
// 设置表单数据
setFormData(data);
+19 -7
View File
@@ -185,6 +185,8 @@ export default function RulesIndex() {
// 添加一个路由变化计数器
const [routeChangeCount, setRouteChangeCount] = useState(0);
// 添加一个状态来跟踪是否执行了删除操作
const [isDeleting, setIsDeleting] = useState(false);
// 获取当前的ruleType值
const ruleTypeParam = searchParams.get('ruleType');
@@ -203,11 +205,11 @@ export default function RulesIndex() {
const isDeveloper = userRole === 'developer';
// 在组件渲染时初始化状态
useEffect(() => {
setFilteredRules(initialRules);
setFilteredTotalCount(initialTotalCount);
setRuleTypes(initialRuleTypes);
}, [initialRules, initialTotalCount, initialRuleTypes]);
// useEffect(() => {
// setFilteredRules(initialRules);
// setFilteredTotalCount(initialTotalCount);
// setRuleTypes(initialRuleTypes);
// }, [initialRules, initialTotalCount, initialRuleTypes]);
// 使用useEffect监听loaderData.error变化并显示Toast
useEffect(() => {
@@ -310,18 +312,26 @@ export default function RulesIndex() {
// loading: 加载中状态
// idle: 空闲状态
useEffect(() => {
if (fetcher.data && fetcher.state === 'idle') {
// 仅在fetcher有数据且状态为idle时处理
if (fetcher.data && fetcher.state === 'idle' && isDeleting) {
// 重置删除状态
setIsDeleting(false);
if (fetcher.data.result) {
toastService.success(fetcher.data.message);
// 删除成功后重新加载数据
fetchData();
} else if (!fetcher.data.result) {
// 删除失败只显示错误信息,不刷新数据
if(fetcher.data.message.includes("evaluation_results_evaluation_point_id_fkey")) {
toastService.error('对表evaluation_points进行更新或删除违反了表evaluation results上的外键约束evaluations results_evaluation _point_id_fkey');
} else {
toastService.error(fetcher.data.message);
}
// 删除失败不刷新数据
}
}
}, [fetcher.data,fetcher.state]);
}, [fetcher.data, fetcher.state, fetchData, isDeleting]);
// 在组件挂载时从 sessionStorage 获取 reviewType 并加载数据
useEffect(() => {
@@ -434,6 +444,8 @@ export default function RulesIndex() {
confirmText: "删除",
cancelText: "取消",
onConfirm: () => {
// 设置删除状态为true
setIsDeleting(true);
const form = new FormData();
form.append("_action", "delete");
form.append("ruleId", rule.id);