92 lines
3.8 KiB
TypeScript
92 lines
3.8 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { FileText, Play, RotateCw } from "lucide-react";
|
|
import { api, formatDateTime } from "@/lib/api";
|
|
import type { FeishuSession, TaskRun } from "@/lib/types";
|
|
import StatusBadge from "./StatusBadge";
|
|
|
|
export default function SessionTable({ sessions, onChanged }: { sessions: FeishuSession[]; onChanged: () => void }) {
|
|
async function run(id: number, reprocess = false) {
|
|
await api.post<TaskRun>(`/sessions/${id}/${reprocess ? "reprocess" : "process"}`, {});
|
|
onChanged();
|
|
}
|
|
|
|
return (
|
|
<div className="table-wrap rounded-md border border-line bg-white">
|
|
<table className="min-w-[1100px] 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">日期</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>
|
|
<th className="px-4 py-3">操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{sessions.map((session) => (
|
|
<tr key={session.id} className="border-t border-line align-top">
|
|
<td className="px-4 py-3">{session.date ?? "-"}</td>
|
|
<td className="px-4 py-3 font-medium text-ink">{session.title}</td>
|
|
<td className="px-4 py-3">{session.teachers ?? "-"}</td>
|
|
<td className="px-4 py-3">
|
|
{session.feishu_doc_url ? (
|
|
<span className="text-jade">{session.feishu_doc_url}</span>
|
|
) : (
|
|
<span className="text-slate-400">-</span>
|
|
)}
|
|
</td>
|
|
<td className="px-4 py-3">
|
|
<StatusBadge status={session.process_status} />
|
|
</td>
|
|
<td className="px-4 py-3">{session.qa_count}</td>
|
|
<td className="px-4 py-3">{session.pending_review_count}</td>
|
|
<td className="px-4 py-3">{session.standard_qa_count}</td>
|
|
<td className="max-w-xs px-4 py-3 text-rose-700">{session.failed_reason ?? "-"}</td>
|
|
<td className="px-4 py-3">
|
|
<div className="flex flex-wrap gap-2">
|
|
<Link
|
|
href={`/sessions/${session.id}`}
|
|
className="inline-flex h-8 items-center gap-1 rounded-md border border-line px-2 text-xs hover:bg-slate-50"
|
|
>
|
|
<FileText className="h-3.5 w-3.5" aria-hidden />
|
|
详情
|
|
</Link>
|
|
<button
|
|
onClick={() => run(session.id)}
|
|
className="inline-flex h-8 items-center gap-1 rounded-md border border-line px-2 text-xs hover:bg-slate-50"
|
|
>
|
|
<Play className="h-3.5 w-3.5" aria-hidden />
|
|
处理
|
|
</button>
|
|
<button
|
|
onClick={() => run(session.id, true)}
|
|
className="inline-flex h-8 items-center gap-1 rounded-md border border-line px-2 text-xs hover:bg-slate-50"
|
|
>
|
|
<RotateCw className="h-3.5 w-3.5" aria-hidden />
|
|
重跑
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
{sessions.length === 0 ? (
|
|
<tr>
|
|
<td className="px-4 py-8 text-center text-slate-500" colSpan={10}>
|
|
暂无场次
|
|
</td>
|
|
</tr>
|
|
) : null}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
}
|
|
|