90 lines
3.7 KiB
TypeScript
90 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { api, formatDateTime } from "@/lib/api";
|
|
import type { AuditLog, TaskRun } from "@/lib/types";
|
|
import StatusBadge from "@/components/StatusBadge";
|
|
|
|
export default function LogsPage() {
|
|
const [tasks, setTasks] = useState<TaskRun[]>([]);
|
|
const [audit, setAudit] = useState<AuditLog[]>([]);
|
|
|
|
useEffect(() => {
|
|
Promise.all([api.get<TaskRun[]>("/logs/tasks"), api.get<AuditLog[]>("/logs/audit")]).then(([taskRows, auditRows]) => {
|
|
setTasks(taskRows);
|
|
setAudit(auditRows);
|
|
});
|
|
}, []);
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<h1 className="text-2xl font-semibold text-ink">运行日志</h1>
|
|
|
|
<div className="table-wrap rounded-md border border-line bg-white">
|
|
<table className="min-w-[980px] w-full border-collapse text-left text-sm">
|
|
<thead className="bg-panel text-xs uppercase text-slate-500">
|
|
<tr>
|
|
<th className="px-4 py-3">任务 ID</th>
|
|
<th className="px-4 py-3">开始时间</th>
|
|
<th className="px-4 py-3">结束时间</th>
|
|
<th className="px-4 py-3">状态</th>
|
|
<th className="px-4 py-3">场次</th>
|
|
<th className="px-4 py-3">问答</th>
|
|
<th className="px-4 py-3">失败</th>
|
|
<th className="px-4 py-3">错误</th>
|
|
<th className="px-4 py-3">重试</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{tasks.map((task) => (
|
|
<tr key={task.id} className="border-t border-line">
|
|
<td className="px-4 py-3">{task.id}</td>
|
|
<td className="px-4 py-3">{formatDateTime(task.started_at)}</td>
|
|
<td className="px-4 py-3">{formatDateTime(task.ended_at)}</td>
|
|
<td className="px-4 py-3">
|
|
<StatusBadge status={task.task_status} />
|
|
</td>
|
|
<td className="px-4 py-3">{task.sessions_processed}/{task.sessions_scanned}</td>
|
|
<td className="px-4 py-3">{task.qa_created}</td>
|
|
<td className="px-4 py-3">{task.qa_failed}</td>
|
|
<td className="px-4 py-3 text-rose-700">{task.error_message ?? "-"}</td>
|
|
<td className="px-4 py-3">{task.retry_count}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div className="table-wrap rounded-md border border-line bg-white">
|
|
<table className="min-w-[900px] w-full border-collapse text-left text-sm">
|
|
<thead className="bg-panel text-xs uppercase text-slate-500">
|
|
<tr>
|
|
<th className="px-4 py-3">日志 ID</th>
|
|
<th className="px-4 py-3">对象</th>
|
|
<th className="px-4 py-3">动作</th>
|
|
<th className="px-4 py-3">前状态</th>
|
|
<th className="px-4 py-3">后状态</th>
|
|
<th className="px-4 py-3">备注</th>
|
|
<th className="px-4 py-3">时间</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{audit.map((log) => (
|
|
<tr key={log.id} className="border-t border-line">
|
|
<td className="px-4 py-3">{log.id}</td>
|
|
<td className="px-4 py-3">{log.target_type} #{log.target_id}</td>
|
|
<td className="px-4 py-3">{log.action}</td>
|
|
<td className="px-4 py-3">{log.before_status ?? "-"}</td>
|
|
<td className="px-4 py-3">{log.after_status ?? "-"}</td>
|
|
<td className="px-4 py-3">{log.comment ?? "-"}</td>
|
|
<td className="px-4 py-3">{formatDateTime(log.created_at)}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|