diff --git a/frontend/src/pages/Deploy/ScheduleJob/List/components/Dashboard.tsx b/frontend/src/pages/Deploy/ScheduleJob/List/components/Dashboard.tsx index 3ecbd1a1..48d80b26 100644 --- a/frontend/src/pages/Deploy/ScheduleJob/List/components/Dashboard.tsx +++ b/frontend/src/pages/Deploy/ScheduleJob/List/components/Dashboard.tsx @@ -19,15 +19,18 @@ import { getDashboard, getScheduleJobs } from '../service'; import type { DashboardResponse, ScheduleJobResponse, LogStatus } from '../types'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; +import duration from 'dayjs/plugin/duration'; import 'dayjs/locale/zh-cn'; dayjs.extend(relativeTime); +dayjs.extend(duration); dayjs.locale('zh-cn'); const Dashboard: React.FC = () => { const [data, setData] = useState(null); const [allJobs, setAllJobs] = useState([]); const [loading, setLoading] = useState(true); + const [currentTime, setCurrentTime] = useState(dayjs()); // 加载仪表盘数据 const loadData = async () => { @@ -52,6 +55,14 @@ const Dashboard: React.FC = () => { return () => clearInterval(interval); }, []); + // 实时更新当前时间(用于倒计时) + useEffect(() => { + const timer = setInterval(() => { + setCurrentTime(dayjs()); + }, 1000); + return () => clearInterval(timer); + }, []); + // 获取日志状态徽章 const getLogStatusBadge = (status: LogStatus) => { const statusMap: Record { .slice(0, 10); }, [allJobs]); + // 格式化倒计时 + const formatCountdown = (nextTime: string) => { + const diff = dayjs(nextTime).diff(currentTime); + if (diff <= 0) return '即将执行'; + const dur = dayjs.duration(diff); + const days = dur.days(); + const hours = dur.hours(); + const minutes = dur.minutes(); + const seconds = dur.seconds(); + + if (days > 0) return `${days}天${hours}小时后`; + if (hours > 0) return `${hours}小时${minutes}分后`; + if (minutes > 0) return `${minutes}分${seconds}秒后`; + return `${seconds}秒后`; + }; + if (loading) { return (
@@ -103,9 +130,9 @@ const Dashboard: React.FC = () => { } return ( -
+
{/* 任务概览统计卡片 */} -
+
任务总数 @@ -166,45 +193,9 @@ const Dashboard: React.FC = () => {
- {/* 正在执行的任务 */} - {data && data.runningJobs.length > 0 && ( - - - - - 正在执行的任务 ({data.runningJobs.length}) - - - - {data.runningJobs.map((job) => ( -
-
-
-

{job.jobName}

-

- 开始时间: {dayjs(job.startTime).format('YYYY-MM-DD HH:mm:ss')} -

-
- - {job.progress}% - -
- - {job.message && ( -

- - {job.message} -

- )} -
- ))} -
-
- )} - {/* 多视图 Tabs */} - - + + 时间线视图 @@ -220,22 +211,23 @@ const Dashboard: React.FC = () => { {/* 时间线视图 */} - - - + + + 任务执行时间线

即将执行的任务按时间顺序排列

- - {upcomingJobs.length === 0 ? ( -
- -

暂无即将执行的任务

-
- ) : ( -
+ + + {upcomingJobs.length === 0 ? ( +
+ +

暂无即将执行的任务

+
+ ) : ( +
{/* 时间线 */}
@@ -274,15 +266,16 @@ const Dashboard: React.FC = () => {
))} -
- )} +
+ )} + {/* 状态分组视图 */} - -
+ +
{/* 运行中 */} @@ -387,7 +380,7 @@ const Dashboard: React.FC = () => {

- 下次: {job.nextExecuteTime ? dayjs(job.nextExecuteTime).format('MM-DD HH:mm') : '-'} + {job.nextExecuteTime ? formatCountdown(job.nextExecuteTime) : '-'}

))} @@ -432,19 +425,20 @@ const Dashboard: React.FC = () => {
{/* 最近日志 */} - - - + + + 最近执行日志 (10条) - - {!data || data.recentLogs.length === 0 ? ( -
- -

暂无执行日志

-
- ) : ( -
+ + + {!data || data.recentLogs.length === 0 ? ( +
+ +

暂无执行日志

+
+ ) : ( +
{data.recentLogs.map((log) => (
@@ -468,8 +462,9 @@ const Dashboard: React.FC = () => { )}
))} -
- )} +
+ )} +