'use client'; /** * 历史归档 /history * 角色:熟手 + 组长(管理员也能进) * 数据:GET /api/v1/tasks?status=approved,archived,rejected */ import { useEffect, useState, useCallback } from 'react'; import { api } from '@/lib/api'; import { TaskListItem, PaginatedResponse } from '@/types'; import { getErrorAction } from '@/types/errors'; import { clsx } from 'clsx'; import { HistoryTable, HistorySkeleton, Pagination } from './components'; const HISTORY_STATUSES = ['approved', 'archived', 'rejected', 'failed']; const STATUS_LABELS: Record = { approved: '已通过', archived: '已归档', rejected: '被打回', failed: '生成失败', }; const PAGE_SIZE = 20; export default function HistoryPage() { const [tasks, setTasks] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [statusFilter, setStatusFilter] = useState('all'); const fetchHistory = useCallback(async (p: number, status: string) => { setLoading(true); setError(null); try { const params = new URLSearchParams({ page: String(p), page_size: String(PAGE_SIZE) }); if (status !== 'all') params.append('status', status); else HISTORY_STATUSES.forEach((s) => params.append('status', s)); const res = await api.get>(`/api/v1/tasks?${params}`); setTasks(res.items); setTotal(res.total); } catch (e: unknown) { const ae = e as { code?: number }; setError(getErrorAction(ae.code ?? 50001).message); } finally { setLoading(false); } }, []); useEffect(() => { fetchHistory(page, statusFilter); }, [page, statusFilter, fetchHistory]); const totalPages = Math.ceil(total / PAGE_SIZE); return (

历史归档

共 {total} 条
{/* 状态筛选 */}
{[{ key: 'all', label: '全部' }, ...HISTORY_STATUSES.map((s) => ({ key: s, label: STATUS_LABELS[s], }))].map((opt) => ( ))}
{error && (
{error}
)} {loading ? : tasks.length === 0 ? (
暂无历史记录
) : ( )} {totalPages > 1 && }
); }