fix(intelligent-eval): task queue all-count + unresolved filter
All checks were successful
CI / test (push) Successful in 4m0s

任务队列全部任务计数把派生的 unresolved 字段也求和了(stats 含
pending/assigned/completed/failed/unresolved),导致显示 9 而实际 8 条。
- 全部任务 = 四态之和(排除 unresolved),与后端 stats 对齐
- 改为一次拉取全部 + 前端过滤(unresolved 是 pending+assigned 并集,
  后端 status 单选无法表达);筛选/分页为前端状态,筛选变化重置到第 1 页
tsc 0 错误 vitest 16 passed
This commit is contained in:
sinohqb 2026-08-18 10:48:13 +08:00
parent 57951f7940
commit 60c545ab78

View File

@ -31,14 +31,15 @@ export default function TaskQueueMonitor() {
pending: number; assigned: number; completed: number; failed: number; unresolved: number pending: number; assigned: number; completed: number; failed: number; unresolved: number
} | null>(null) } | null>(null)
const [filter, setFilter] = useState<FilterKey>('all') const [filter, setFilter] = useState<FilterKey>('all')
const [page, setPage] = useState(1)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
// 一次拉取全部任务筛选在前端完成数据量小unresolved 是 pending+assigned 并集,
// 后端 status 筛选无法一次表达,且 stats 含派生的 unresolved不能直接求和当总数
const loadData = async () => { const loadData = async () => {
setLoading(true) setLoading(true)
try { try {
const res = await intelligentEvalsApi.listTasks( const res = await intelligentEvalsApi.listTasks()
filter === 'all' || filter === 'unresolved' ? undefined : { status: filter },
)
setTasks(res.data.tasks) setTasks(res.data.tasks)
setStats(res.data.stats) setStats(res.data.stats)
} catch { } catch {
@ -48,16 +49,31 @@ export default function TaskQueueMonitor() {
} }
} }
// Initial fetch + reload on filter change (usePolling owns the 5s interval). // Initial fetch (usePolling owns the 5s interval). 筛选/分页为前端状态。
useEffect(() => { useEffect(() => {
void loadData() void loadData()
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
// 筛选变化时回到第 1 页
useEffect(() => {
setPage(1)
}, [filter]) }, [filter])
usePolling(() => { void loadData() }, 5000, true) usePolling(() => { void loadData() }, 5000, true)
const allTasks = tasks ?? []
const visibleTasks = filter === 'all'
? allTasks
: filter === 'unresolved'
? allTasks.filter((t) => t.status === 'pending' || t.status === 'assigned')
: allTasks.filter((t) => t.status === filter)
// 全部任务 = 四态之和(不含派生的 unresolved与后端 stats 对齐
const totalAll = stats ? stats.pending + stats.assigned + stats.completed + stats.failed : allTasks.length
const chipMeta: { key: FilterKey; label: string; color?: string; get: () => number }[] = [ const chipMeta: { key: FilterKey; label: string; color?: string; get: () => number }[] = [
{ key: 'all', label: '全部任务', get: () => (stats ? Object.values(stats).reduce((a, b) => a + b, 0) : (tasks?.length ?? 0)) }, { key: 'all', label: '全部任务', get: () => totalAll },
{ key: 'unresolved', label: '待处理', color: colors.warning, get: () => stats?.unresolved ?? 0 }, { key: 'unresolved', label: '待处理', color: colors.warning, get: () => stats?.unresolved ?? 0 },
{ key: 'pending', label: '待认领', get: () => stats?.pending ?? 0 }, { key: 'pending', label: '待认领', get: () => stats?.pending ?? 0 },
{ key: 'assigned', label: '执行中', color: colors.primary, get: () => stats?.assigned ?? 0 }, { key: 'assigned', label: '执行中', color: colors.primary, get: () => stats?.assigned ?? 0 },
@ -132,13 +148,16 @@ export default function TaskQueueMonitor() {
<Table <Table
rowKey="id" rowKey="id"
loading={loading} loading={loading}
dataSource={tasks ?? []} dataSource={visibleTasks}
columns={columns} columns={columns}
pagination={{ pagination={{
current: page,
pageSize: 10, pageSize: 10,
total: visibleTasks.length,
showSizeChanger: true, showSizeChanger: true,
pageSizeOptions: [10, 20, 50], pageSizeOptions: [10, 20, 50],
showTotal: (t) => `${t}`, showTotal: (t) => `${t}`,
onChange: (p) => setPage(p),
}} }}
locale={{ emptyText: <Empty description="暂无任务" /> }} locale={{ emptyText: <Empty description="暂无任务" /> }}
/> />