/** * filekorolheader: 审核历史页面 - 企业审核记录查询和管理页面 * 功能:审核历史记录查询、搜索筛选、详情查看、数据分析 * 路径:/central-config/tenant/audit-history * 规范:遵循crop-x-new/docs/开发项目规范.md,使用SearchFormPagination组件,API集成,shadcn语义化样式 */ 'use client'; import React, { 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'; import { Label } from '@/components/ui/label'; import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; import { FileText, AlertCircle, RefreshCw, Building, User, Smartphone, Search } from 'lucide-react'; import { toast } from 'sonner'; import SearchFormPagination, { type SearchFieldConfig, type TableColumnConfig } from '@/components/common/searchFormPagination'; import { fetchAuditLogs, transformAuditLogData, AuditLogsQueryParams, AuditRecord, AuditLogData } from './components/auditHistoryApi'; // URL参数类型定义 interface UrlParams { search?: string; action?: string; audit_status?: string; date_range?: string; page?: number; size?: number; } // 分页状态类型定义 interface PaginationState { page: number; size: number; total: number; totalPages: number; hasNext: boolean; hasPrev: boolean; } // Utility functions const getActionBadge = (action: string) => { switch (action) { case 'SUBMIT': return (
提交审核
); case 'AUDIT': return (
审核操作
); default: return (
{action}
); } }; const getResultBadge = (result: string) => { switch (result) { case 'approved': return (
已通过
); case 'rejected': return (
已拒绝
); case 'pending': return (
待审核
); case 'draft': return (
草稿
); default: return (
{result}
); } }; export default function AuditHistoryPage() { // 对话框状态管理 const [dialogs, setDialogs] = useState({ showViewDialog: false, selectedRecord: null as AuditRecord | null }); const dispatch = (action: any) => { switch (action.type) { case 'SET_SELECTED_RECORD': setDialogs(prev => ({ ...prev, selectedRecord: action.payload })); break; case 'TOGGLE_VIEW_DIALOG': setDialogs(prev => ({ ...prev, showViewDialog: action.payload })); break; case 'RESET_FORM_DATA': setDialogs(prev => ({ ...prev, selectedRecord: null })); break; } }; // 搜索字段配置 const searchFields: SearchFieldConfig[] = [ { key: 'search', label: '搜索', type: 'text', placeholder: '搜索企业名称、变更摘要...', }, { key: 'action', label: '审核类型', type: 'select', defaultValue: 'all', options: [ { value: 'all', label: '全部类型' }, { value: 'SUBMIT', label: '提交审核' }, { value: 'AUDIT', label: '审核操作' }, ], }, { key: 'audit_status', label: '审核结果', type: 'select', defaultValue: 'all', options: [ { value: 'all', label: '全部结果' }, { value: 'approved', label: '已通过' }, { value: 'rejected', label: '已拒绝' }, { value: 'pending', label: '待审核' }, { value: 'draft', label: '草稿' }, ], }, { key: 'date_range', label: '时间范围', type: 'select', defaultValue: 'all', options: [ { value: 'all', label: '全部' }, { value: 'today', label: '今天' }, { value: 'week', label: '近7天' }, { value: 'month', label: '近30天' }, { value: 'quarter', label: '近90天' }, ], }, ]; // 表格列配置 const columns: TableColumnConfig[] = [ { key: 'enterpriseName', label: '企业名称', render: (value: string) => (
{value}
), }, { key: 'action', label: '审核类型', render: (value: string) => getActionBadge(value), }, { key: 'submitTime', label: '提交时间', render: (value: string, record: AuditLogData) => (
{record.action === 'SUBMIT' ? value : '-'}
), }, { key: 'actionTime', label: '审核时间', render: (value: string, record: AuditLogData) => (
{record.action === 'AUDIT' ? value : '-'}
), }, { key: 'actionBy', label: '审核人', render: (value: string) => value ? (
{value}
) : '-', }, { key: 'result', label: '审核结果', render: (value: string) => getResultBadge(value), }, { key: 'actions', label: '操作', render: (_: any, row: AuditLogData) => ( ), }, ]; // 简化的状态管理 - 只需要存储数据和加载状态 const [records, setRecords] = useState([]); const [pagination, setPagination] = useState({ page: 1, size: 10, total: 0, totalPages: 0, hasNext: false, hasPrev: false, }); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [searchFilters, setSearchFilters] = useState>({ search: '', action: 'all', audit_status: 'all', date_range: 'all' }); // 数据加载函数 - 优先从浏览器URL参数读取 const loadAuditHistory = useCallback(async (options: { resetPage?: boolean; filters?: Record; sortBy?: string; sortOrder?: 'asc' | 'desc'; page?: number; size?: number; } = {}) => { try { // 优先从URL读取参数 let urlParams: UrlParams = {}; if (typeof window !== 'undefined') { const params = new URLSearchParams(window.location.search); urlParams = { search: params.get('search') || undefined, action: params.get('action') || undefined, audit_status: params.get('audit_status') || undefined, date_range: params.get('date_range') || undefined, page: params.get('page') ? parseInt(params.get('page')!, 10) : undefined, size: params.get('size') ? parseInt(params.get('size')!, 10) : undefined }; console.log('从URL读取的参数:', urlParams); } console.log('========================================'); setLoading(true); setError(null); // 解构选项参数,提供默认值 const { resetPage = false, filters, sortBy, sortOrder, page, size } = options; // 优先级:URL参数 > 传入参数 > 父组件状态 const finalPage = resetPage ? 1 : (urlParams.page || page || pagination.page); const finalSize = urlParams.size || size || pagination.size; const params: AuditLogsQueryParams = { page: finalPage, size: finalSize, }; // 使用正确的优先级:URL参数 > 传入参数 > 父组件状态 const currentFilters = { search: urlParams.search || (filters?.search) || searchFilters.search, action: urlParams.action || (filters?.action) || searchFilters.action, audit_status: urlParams.audit_status || (filters?.audit_status) || searchFilters.audit_status, date_range: urlParams.date_range || (filters?.date_range) || searchFilters.date_range }; const currentSortBy = sortBy || 'created_at'; const currentSortOrder = sortOrder || 'desc'; // 添加搜索条件 if (currentFilters.search) { params.search_keyword = currentFilters.search; } // 添加排序条件 if (currentSortBy) { params.order_by = currentSortBy; params.sort_order = currentSortOrder; } if (currentFilters.action && currentFilters.action !== 'all') { params.action = currentFilters.action; } if (currentFilters.audit_status && currentFilters.audit_status !== 'all') { params.audit_status = currentFilters.audit_status; } if (currentFilters.date_range && currentFilters.date_range !== 'all') { params.date_range = currentFilters.date_range; } if (currentSortBy) { params.order_by = currentSortBy; params.sort_order = currentSortOrder; } console.log('=== 审核历史页面 - 最终API参数 ==='); console.log('API调用参数 params:', params); console.log('参数优先级正确: URL参数 > 函数传递参数 > 父组件状态'); console.log('当前currentFilters:', currentFilters); console.log('=================================='); const response = await fetchAuditLogs(params); 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); toast.error(errorMessage); } finally { setLoading(false); } }, []); // 移除依赖项,通过参数传递 const didFetchRef = useRef(false) useEffect(() => { if (didFetchRef.current) return didFetchRef.current = true loadAuditHistory() }, []) // 搜索处理 - 保持传统的简洁方式 const handleSearch = useCallback((filters: Record) => { console.log('审核历史页面 - 收到搜索条件:', filters); // 更新过滤器状态 setSearchFilters(filters); // 搜索时重置到第1页 setPagination(prev => ({ ...prev, page: 1 })); // 执行查询 loadAuditHistory({ resetPage: true, page: 1, filters: filters, size: pagination.size }); console.log('触发审核历史查询 - 参数:', { resetPage: true, page: 1, filters: filters, size: pagination.size }); }, [pagination.size, loadAuditHistory]); // 排序处理 const handleSort = useCallback((sortBy: string, sortOrder: 'asc' | 'desc') => { // 排序时重置到第一页 setPagination(prev => ({ ...prev, page: 1 })); loadAuditHistory({ resetPage: true, page: 1, filters: searchFilters, sortBy, sortOrder, size: pagination.size }); }, [searchFilters, pagination.size, loadAuditHistory]); // 分页处理 const handlePageChange = useCallback((page: number) => { if (page < 1) { page = 1; } else if (page > pagination.totalPages && pagination.totalPages > 0) { page = pagination.totalPages; } setPagination(prev => ({ ...prev, page })); loadAuditHistory({ page, filters: searchFilters, size: pagination.size }); }, [searchFilters, pagination.size, pagination.totalPages, loadAuditHistory]); // 每页条数变化处理 const handleSizeChange = useCallback((size: number) => { setPagination(prev => ({ ...prev, size, page: 1 })); loadAuditHistory({ resetPage: true, page: 1, size, filters: searchFilters }); }, [searchFilters, loadAuditHistory]); // URL状态变化处理 - 处理浏览器前进后退时的参数恢复 const handleUrlStateChange = useCallback((urlState: { filters: Record; pagination: { page: number; size: number }; }) => { console.log('审核历史页面 - URL状态变化:', urlState); // 更新内部状态 setSearchFilters(urlState.filters); setPagination(prev => ({ ...prev, page: urlState.pagination.page, size: urlState.pagination.size })); // 触发数据加载 loadAuditHistory({ page: urlState.pagination.page, size: urlState.pagination.size, filters: urlState.filters }); }, [loadAuditHistory]); // 业务事件处理器 const handleView = (record: AuditLogData) => { dispatch({ type: 'SET_SELECTED_RECORD', payload: record }); dispatch({ type: 'TOGGLE_VIEW_DIALOG', payload: true }); }; return (
{/* Page Header - 自定义页面头部 */}

审核历史

追溯查询全部企业的历史审核记录,支持搜索筛选和详情查看

智能查询
状态筛选
详情查看
{/* 使用SearchFormPagination组件 */} {React.createElement(SearchFormPagination as any, { formTitle: "审核历史记录", searchFields, columns, data: records, loading, error, pagination: pagination as any, onPageChange: handlePageChange, onSizeChange: handleSizeChange, onSearch: handleSearch, onSort: handleSort, emptyIcon: , emptyText: "暂无审核记录", sizeOptions: [10, 20, 50, 100] })} {/* View Audit Record Details Dialog */} dispatch({ type: 'TOGGLE_VIEW_DIALOG', payload: open })}> 审核记录详情 查看审核记录的详细信息和企业快照数据 {dialogs.selectedRecord && ( 基本信息 企业快照 系统信息 {/* 基本信息 */}
{dialogs.selectedRecord.enterpriseName}
{getActionBadge(dialogs.selectedRecord.action)}
{dialogs.selectedRecord.action === 'SUBMIT' ? dialogs.selectedRecord.submitTime : '-'}
{dialogs.selectedRecord.action === 'AUDIT' ? dialogs.selectedRecord.actionTime : '-'}
{dialogs.selectedRecord.actionBy || '-'}
{getResultBadge(dialogs.selectedRecord.result)}
{dialogs.selectedRecord.changeSummary || '-'}
{dialogs.selectedRecord.auditComment || '-'}
{/* 企业快照 */}
{dialogs.selectedRecord.snapshot?.companyType || '-'}
{dialogs.selectedRecord.snapshot?.province} {dialogs.selectedRecord.snapshot?.city}
{dialogs.selectedRecord.snapshot?.detailedAddress || '-'}
{dialogs.selectedRecord.snapshot?.registrant || '-'}
{dialogs.selectedRecord.snapshot?.contactPhone || '-'}
{dialogs.selectedRecord.snapshot?.companyScale || '-'}
{dialogs.selectedRecord.snapshot?.registeredCapital || '-'}
{dialogs.selectedRecord.snapshot?.socialCreditCode || '-'}
{dialogs.selectedRecord.snapshot?.legalPersonName || '-'}
{dialogs.selectedRecord.snapshot?.bankAccount || '-'}
{dialogs.selectedRecord.snapshot?.bankName || '-'}
{dialogs.selectedRecord.snapshot?.bankFullName || '-'}
{dialogs.selectedRecord.snapshot?.bankAddress || '-'}
{/* 系统信息 */}
{dialogs.selectedRecord.id}
{dialogs.selectedRecord.enterpriseId || '-'}
{dialogs.selectedRecord.ipAddress || '-'}
{dialogs.selectedRecord.userAgent || '-'}
{dialogs.selectedRecord.requestId || '-'}
{dialogs.selectedRecord.createdAt}
)}
); }