生产管理系统 - 修改form组件

This commit is contained in:
2025-11-10 16:21:04 +08:00
parent 9217bf888e
commit 91e2c19afd
5 changed files with 122 additions and 55 deletions

View File

@@ -6,7 +6,7 @@
*/
'use client';
import { useMemo, useState, useCallback } from 'react';
import { useMemo, useState, useCallback, useEffect ,useRef} from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { ScrollArea } from '@/components/ui/scroll-area';
@@ -223,7 +223,6 @@ export default function AuditHistoryPage() {
),
},
];
// 简化的状态管理 - 只需要存储数据和加载状态
const [records, setRecords] = useState<AuditLogData[]>([]);
const [pagination, setPagination] = useState({
@@ -280,14 +279,6 @@ export default function AuditHistoryPage() {
const transformedData = response.data.map(transformAuditLogData);
setRecords(transformedData);
setPagination({
page: response.page,
size: response.size,
total: response.total,
totalPages: response.total_pages,
hasNext: response.has_next,
hasPrev: response.has_prev,
});
} catch (err) {
const errorMessage = err instanceof Error ? err.message : '加载审核历史失败';
setError(errorMessage);
@@ -295,8 +286,15 @@ export default function AuditHistoryPage() {
} finally {
setLoading(false);
}
}, []); // 移除所有依赖,使用参数传递状态变化
}, [searchFilters, pagination]); // 添加依赖以保持函数引用最新
const didFetchRef = useRef(false)
useEffect(() => {
if (didFetchRef.current) return
didFetchRef.current = true
loadAuditHistory()
}, [])
// 事件处理器
const handleSearch = useCallback((filters: Record<string, string>) => {
setSearchFilters(filters);
@@ -315,18 +313,6 @@ export default function AuditHistoryPage() {
});
}, [loadAuditHistory, pagination.size]);
// 统一的数据重载函数 - 避免重复代码
const reloadData = useCallback(() => {
const reloadParams = {
filters: searchFilters,
pagination: {
page: pagination.page,
size: pagination.size
}
};
loadAuditHistory(reloadParams);
}, [loadAuditHistory, searchFilters, pagination]);
const handlePageChange = useCallback((page: number) => {
setPagination(prev => ({ ...prev, page }));
loadAuditHistory({
@@ -334,7 +320,6 @@ export default function AuditHistoryPage() {
pagination: { page, size: pagination.size }
});
}, [loadAuditHistory, searchFilters, pagination.size]);
const handleSizeChange = useCallback((size: number) => {
setPagination(prev => ({ ...prev, size, page: 1 }));
loadAuditHistory({

View File

@@ -221,7 +221,12 @@ export default function EnterpriseAuditPage() {
),
},
];
const didFetchRef = useRef(false)
useEffect(() => {
if (didFetchRef.current) return
didFetchRef.current = true
loadEnterprises()
}, [])
// 加载企业数据 - 移除依赖项,通过参数传递状态
const loadEnterprises = useCallback(async (params?: {
filters?: Record<string, string>;

View File

@@ -6,7 +6,7 @@
*/
'use client';
import { useEffect, useMemo, useState, useCallback } from 'react';
import { useEffect, useMemo, useState, useCallback ,useRef} from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog';
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
@@ -240,7 +240,12 @@ export default function EnterpriseManagement() {
search: '',
audit_status: 'all'
});
const didFetchRef = useRef(false)
useEffect(() => {
if (didFetchRef.current) return
didFetchRef.current = true
loadEnterprises()
}, [])
// 数据加载函数 - 移除不必要的依赖避免重复调用
const loadEnterprises = useCallback(async (params?: {
filters?: Record<string, string>;

View File

@@ -6,7 +6,7 @@
*/
'use client';
import { useReducer, useEffect, useState, useCallback, useMemo } from 'react';
import { useReducer, useEffect, useState, useCallback, useMemo,useRef } from 'react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Eye, Edit, Lock, UserX, UserCheck } from 'lucide-react';
@@ -100,7 +100,6 @@ const initialState: UserManagementState = {
export default function TenantUserManagementPage() {
const [state, dispatch] = useReducer(userManagementReducer, initialState);
const [searchFilters, setSearchFilters] = useState<Record<string, string>>({});
// 搜索字段配置
const searchFields: SearchFieldConfig[] = useMemo(() => [
@@ -274,32 +273,55 @@ export default function TenantUserManagementPage() {
], []);
// 加载用户数据
const loadUsers = useCallback(async (resetPage = false) => {
const loadUsers = useCallback(async (options: {
resetPage?: boolean;
filters?: UserFilters;
sortBy?: string;
sortOrder?: 'asc' | 'desc';
page?: number;
size?: number;
} = {}) => {
try {
dispatch({ type: 'SET_LOADING', payload: true });
// 解构选项参数,提供默认值
const {
resetPage = false,
filters,
sortBy,
sortOrder,
page,
size
} = options;
const params: UsersQueryParams = {
page: resetPage ? 1 : state.pagination.page,
size: state.pagination.size,
page: resetPage ? 1 : (page || state.pagination.page),
size: size || state.pagination.size,
is_active: true,
};
// 使用传入的过滤器参数,如果没有传入则使用当前状态
const currentFilters = filters || state.filters;
const currentSortBy = sortBy || state.sortBy;
const currentSortOrder = sortOrder || state.sortOrder;
// 添加搜索条件
if (searchFilters.search) {
params.search = searchFilters.search;
if (currentFilters.searchKeyword) {
params.search = currentFilters.searchKeyword;
}
if (searchFilters.status && searchFilters.status !== 'all') {
params.is_active = searchFilters.status === 'active';
if (currentFilters.statusFilter && currentFilters.statusFilter !== 'all') {
params.is_active = currentFilters.statusFilter === 'active';
}
if (searchFilters.type && searchFilters.type !== 'all') {
if (currentFilters.typeFilter && currentFilters.typeFilter !== 'all') {
// For user type filtering, we'll need to handle this differently based on the API
// For now, we'll filter on the client side if needed
}
if (state.sortBy) {
params.order_by = state.sortBy;
params.sort_order = state.sortOrder;
if (currentSortBy) {
params.order_by = currentSortBy;
params.sort_order = currentSortOrder;
}
const response: UsersApiResponse = await fetchUsers(params);
@@ -330,14 +352,35 @@ export default function TenantUserManagementPage() {
// 搜索处理
const handleSearch = useCallback((filters: Record<string, string>) => {
setSearchFilters(filters);
const mappedFilters = {
searchKeyword: filters.search || '',
statusFilter: filters.status || 'all',
typeFilter: filters.type || 'all'
};
dispatch({ type: 'SET_FILTERS', payload: mappedFilters });
dispatch({ type: 'SET_PAGINATION', payload: { page: 1 } });
}, []);
// 传入所有当前参数,避免覆盖其他参数
loadUsers({
resetPage: true,
filters: mappedFilters,
sortBy: state.sortBy,
sortOrder: state.sortOrder,
size: state.pagination.size
});
}, [state.sortBy, state.sortOrder, state.pagination.size]);
// 排序处理
const handleSort = useCallback((sortBy: string, sortOrder: 'asc' | 'desc') => {
dispatch({ type: 'SET_SORT', payload: { sortBy, sortOrder } });
}, []);
// 传入所有当前参数,避免覆盖其他参数
loadUsers({
resetPage: true,
filters: state.filters,
sortBy,
sortOrder,
size: state.pagination.size
});
}, [state.filters, state.pagination.size]);
// 分页处理
const handlePageChange = useCallback((page: number) => {
@@ -347,12 +390,29 @@ export default function TenantUserManagementPage() {
page = state.pagination.totalPages;
}
dispatch({ type: 'SET_PAGINATION', payload: { page } });
}, [state.pagination.totalPages]);
// 传入所有当前参数,避免覆盖其他参数
loadUsers({
page,
filters: state.filters,
sortBy: state.sortBy,
sortOrder: state.sortOrder,
size: state.pagination.size
});
}, [state.filters, state.sortBy, state.sortOrder, state.pagination.size, state.pagination.totalPages]);
// 每页条数变化处理
const handleSizeChange = useCallback((size: number) => {
dispatch({ type: 'SET_PAGINATION', payload: { size, page: 1 } });
}, []);
// 传入所有当前参数,避免覆盖其他参数
loadUsers({
resetPage: true,
page: 1,
size,
filters: state.filters,
sortBy: state.sortBy,
sortOrder: state.sortOrder
});
}, [state.filters, state.sortBy, state.sortOrder]);
// 查看详情
const handleViewDetail = (user: User) => {
@@ -407,10 +467,12 @@ export default function TenantUserManagementPage() {
},
], [state.users, state.pagination.total]);
// 加载数据
const didFetchRef = useRef(false)
useEffect(() => {
loadUsers();
}, []);
if (didFetchRef.current) return
didFetchRef.current = true
loadUsers({})
}, [])
return (
<div className="space-y-6">

View File

@@ -58,25 +58,35 @@ export function SearchFormComponent({
const newFilters = {
...localFilters,
[key]: value,
// 添加特殊的标记字段来跟踪最后变化的字段类型
_lastChangedFieldType: fieldType,
_lastChangedFieldKey: key,
};
setLocalFilters(newFilters);
// 下拉框选择立即触发查询,文本输入使用防抖
if (fieldType === 'select') {
onFiltersChangeRef.current(newFilters);
// 移除标记字段后再传递给父组件
const { _lastChangedFieldType, _lastChangedFieldKey, ...cleanFilters } = newFilters;
onFiltersChangeRef.current(cleanFilters);
}
// 文本输入的防抖在useEffect中处理
};
// 使用防抖来减少搜索频率,仅针对文本输入
useEffect(() => {
// 只有当最后变化的是 text 字段时才进行防抖,排除初始化和 select 字段
if (localFilters._lastChangedFieldType === 'text') {
const timer = setTimeout(() => {
// 移除标记字段后再调用
const { _lastChangedFieldType, _lastChangedFieldKey, ...cleanFilters } = localFilters;
// 使用ref引用最新的onFiltersChange函数避免依赖变化导致重复触发
onFiltersChangeRef.current(localFilters);
onFiltersChangeRef.current(cleanFilters);
}, 300); // 300ms 防抖延迟
return () => clearTimeout(timer);
}, [localFilters]); // 只依赖localFilters使用ref避免函数依赖问题
}
}, [localFilters]); // 只依赖localFilters
// 计算显示的字段
const visibleFields = showAllFields