// src/app/admin/tasks/page.tsx 'use client'; import { useState, useEffect } from 'react'; import api from '@/lib/api'; import { RefreshCw, Search } from 'lucide-react'; // 组件导入 import TaskTable, { VasTask } from '@/components/admin/tasks/TaskTable'; import TaskDetailModal from '@/components/admin/tasks/TaskDetailModal'; import TaskEditModal from '@/components/admin/tasks/TaskEditModal'; import Pagination from '@/components/common/Pagination'; import ExpiringTaskAlert from '@/components/admin/tasks/ExpiringTaskAlert'; // [新增] 紧急任务组件 export default function AdminTasksPage() { // === 状态定义 === const [tasks, setTasks] = useState([]); const [loading, setLoading] = useState(true); // 分页、搜索、筛选状态 const [page, setPage] = useState(1); const [pageSize] = useState(10); const [total, setTotal] = useState(0); const [keyword, setKeyword] = useState(''); const [statusFilter, setStatusFilter] = useState('all'); // 弹窗状态 const [selectedTask, setSelectedTask] = useState(null); const [isDetailOpen, setIsDetailOpen] = useState(false); const [isEditOpen, setIsEditOpen] = useState(false); // === 数据获取逻辑 === const fetchTasks = async (targetPage: number = page) => { setLoading(true); try { const params: any = { keyword, page: targetPage, size: pageSize, }; if (statusFilter !== 'all') { params.status = statusFilter; } const res = await api.get('/api/vas/task/list', { params }); const data = res.data.data || {}; // 兼容两种常见的分页返回格式 if (Array.isArray(data)) { setTasks(data); setTotal(data.length); } else { setTasks(data.items || []); setTotal(data.total || 0); } setPage(targetPage); } catch (e) { console.warn("API Error, maybe using mock data or network failed"); setTasks([]); setTotal(0); } finally { setLoading(false); } }; // 监听筛选条件变化,自动刷新 useEffect(() => { fetchTasks(1); }, [statusFilter]); // === 事件处理 === const handleSearch = () => { fetchTasks(1); }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') handleSearch(); }; // 重置任务回队列 const handleRetry = async (taskId: number) => { if(!confirm("确定要重置该任务回队列吗?状态将变为 pending。")) return; try { await api.post('/api/vas/task/return_to_queue', null, { params: { task_id: taskId } }); alert("操作成功"); fetchTasks(page); } catch (e) { alert("操作失败"); } }; // 强制标记完成 const handleConfirm = async (taskId: number) => { if(!confirm("确定要强制标记完成吗?这将跳过后续脚本执行。")) return; try { await api.post('/api/vas/task/manual_confirm', null, { params: { task_id: taskId } }); alert("操作成功"); fetchTasks(page); } catch (e) { alert("操作失败"); } }; // 打开详情弹窗 const handleViewDetail = (task: VasTask) => { setSelectedTask(task); setIsDetailOpen(true); }; // 打开编辑弹窗 const handleEdit = (task: VasTask) => { setSelectedTask(task); setIsEditOpen(true); }; // 提交编辑 const handleSubmitEdit = async (taskId: number, data: any) => { try { await api.post('/api/vas/task/update', data, {params: {"id": taskId}}); alert("任务更新成功"); setIsEditOpen(false); fetchTasks(page); // 刷新列表 } catch (e: any) { alert("更新失败: " + (e.response?.data?.message || "未知错误")); } }; return (
{/* === 1. 头部区域 === */}
{/* 标题 */}

系统任务队列

监控机器人执行状态及调试日志

{/* 操作区:筛选、搜索、刷新 */}
{/* 状态筛选下拉框 */} {/* 搜索框组 */}
setKeyword(e.target.value)} onKeyDown={handleKeyDown} />
{/* === [新增] 2. 紧急任务预警区域 === */} {/* 如果有即将过期的任务,这个组件会自动显示;否则不渲染 */} {/* === 3. 主表格区域 === */} {/* === 4. 分页区域 === */}
fetchTasks(p)} />
{/* === 5. 弹窗组件 === */} setIsDetailOpen(false)} task={selectedTask} /> setIsEditOpen(false)} task={selectedTask} onSubmit={handleSubmitEdit} />
); }