diff --git a/web/src/app/(main)/function/schedules/page.tsx b/web/src/app/(main)/function/schedules/page.tsx
index e0f2fd0..28ab74a 100644
--- a/web/src/app/(main)/function/schedules/page.tsx
+++ b/web/src/app/(main)/function/schedules/page.tsx
@@ -25,6 +25,7 @@ import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
+import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { api, type ScheduleInput } from "@/lib/api";
import type { Task, TaskSchedule } from "@/lib/types";
@@ -93,6 +94,21 @@ function windowLabel(item: TaskSchedule) {
return `${start} 至 ${end}${end <= start ? "(次日)" : ""}`;
}
+function startLabel(item: TaskSchedule) {
+ return item.schedule_type === "once"
+ ? `${formatDateValue(item.run_date)} ${formatClock(item.start_time)}`
+ : formatClock(item.start_time);
+}
+
+function endLabel(item: TaskSchedule) {
+ if (!item.end_time) return "持续运行";
+ const end = formatClock(item.end_time);
+ if (item.schedule_type === "once" && item.end_date)
+ return `${formatDateValue(item.end_date)} ${end === "未设置" ? "24:00" : end}`;
+ const start = formatClock(item.start_time);
+ return `${end}${end <= start ? "(次日)" : ""}`;
+}
+
function timezoneLabel(item: TaskSchedule) {
return item.timezone_mode === "beijing" ? "中国北京时间" : `系统时区${item.timezone ? `(${item.timezone})` : ""}`;
}
@@ -554,117 +570,139 @@ export default function SchedulesPage() {
没有匹配的计划任务。
) : (
-
- {visibleItems.map((item) => (
-
-
-
-
-
+
+
+
+
+ 计划名称
+ 运行周期
+ 开始时间
+ 结束时间
+ 运行次数
+ 绑定任务
+ 状态
+ 操作
+
+
+
+ {visibleItems.map((item) => (
+
+
+
{item.name}
计划 #{item.id}
-
-
- {statusText(item)}
-
-
- {timezoneLabel(item)}
-
-
-
- 运行周期:
- {periodLabel(item)}
-
-
- 时间窗口:
- {windowLabel(item)}
-
-
- 绑定任务:
- {item.task_ids.length
- ? `${item.task_ids.length} 个(${item.task_ids.map((id) => `#${id}`).join("、")})`
- : "无"}
-
-
-
-
- 下一次开始:
- {nextWindowLabel(item.next_start, item.timezone)}
-
-
- 下一次结束:
- {nextWindowLabel(item.next_end, item.timezone)}
-
-
- 运行次数:
- {item.run_count ?? 0} 次{item.last_run_at ? ` · 最近 ${formatTime(item.last_run_at)}` : ""}
-
-
- 最近变化:{formatTime(item.last_transition_at)}
- {item.last_error ? ` · ${scheduleErrorText(item.last_error)}` : ""}
-
-
-
-
-
- {item.enabled ? (
-
- ) : (
-
- )}
-
-
-
-
- {expandedId === item.id ? (
-
-
-
- ) : null}
-
- ))}
+
+ {periodLabel(item)}
+
+ {startLabel(item)}
+ {item.next_start ? (
+
+ 下次:{nextWindowLabel(item.next_start, item.timezone)}
+
+ ) : null}
+
+
+ {endLabel(item)}
+ {item.next_end ? (
+
+ 下次:{nextWindowLabel(item.next_end, item.timezone)}
+
+ ) : null}
+
+
+ {item.run_count ?? 0}
+ {item.last_run_at ? (
+ 最近 {formatTime(item.last_run_at)}
+ ) : null}
+
+ `#${id}`).join("、")}
+ >
+ {item.task_ids.length ? item.task_ids.map((id) => `#${id}`).join("、") : "无"}
+
+
+ {statusText(item)}
+ {timezoneLabel(item)}
+
+ 最近:{formatTime(item.last_transition_at)}
+
+ {item.last_error ? (
+
+ {scheduleErrorText(item.last_error)}
+
+ ) : null}
+
+
+
+
+
+ {item.enabled ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ {expandedId === item.id ? (
+
+
+
+
+
+ ) : null}
+
+ ))}
+
+
)}