写一个遍历已完成和未完成任务
效果图
封装一个自动耗时
import { RunStatus } from '@/enums/RunStatus';
import { useEffect, useState } from '@alipay/bigfish/react';
import moment from 'moment';
/**
* 自动输出任务执行耗时
* @param runHistory
*/
export const useTaskDuration = (
runHistory: { GmtCreateTime?: string; Status?: RunStatus } = {},
) => {
const [countUp, setCountUp] = useState<number>(0);
// 设置时间(获得的是当时的时间)
useEffect(() => {
if (runHistory.GmtCreateTime) {
setCountUp(new Date(runHistory.GmtCreateTime).getTime());
}
}, [runHistory.GmtCreateTime]);
// 如果状态是运行中, 启动定时器
useEffect(() => {
if (runHistory.Status === RunStatus.Running) {
const timer = window.setInterval(() => {
setCountUp((prevState) => prevState + 1);
}, 1000);
return () => window.clearInterval(timer);
}
return;
}, [runHistory.Status]);
// console.log('moment',moment());
const duration = moment.duration(moment().diff(moment(countUp)));
return `${duration.hours() !== 0 ? duration.hours() + '小时' : ''} ${duration.minutes()}分${duration.seconds()}秒`;
};
封装一个TaskDetail
const TaskDetail = (props: { row: RunHistory; stopCB?: CallableFunction }) => {
const runHistory = props.row;
const durationText = useTaskDuration(runHistory);
return (
<Row
className={CX([styles.row, runHistory.RunMode === RunMode.DEBUG && styles.clickable])}
onClick={() => onDetailClick(runHistory)}
align={'middle'}
justify={'space-between'}
>
<Col style={{ display: 'flex' }}>
<Tag color={runHistory.RunMode === RunMode.ROUNDED ? 'blue' : 'magenta'}>
{getRunHistoryTypeName(runHistory)}
</Tag>
<SingleLineWrap title={runHistory.Name} width={150} />
</Col>
<Col style={{ display: 'flex', alignItems: 'center' }}>
{runHistory.Status === RunStatus.Running && (
<>
<LoadingOutlined style={{ color: '#1890ff', marginRight: 8 }} />
<span style={{ color: '#1890ff' }}>{durationText}</span>
<Popconfirm
okText={'确认'}
cancelText={'取消'}
onConfirm={() => {
RunService.StopRun(runHistory.Id).then(() => {
message.success('终止运行成功');
props.stopCB?.();
});
}}
title={'您确定要终止运行任务吗?这个操作一旦执行就不能撤回。'}
>
<Button
type={'text'}
className={styles.hoverButton}
danger
onClick={(event) => event.stopPropagation()}
icon={<CloseOutlined />}
/>
</Popconfirm>
</>
)}
{runHistory.Status === RunStatus.Success && (
<Badge {...statusValueBadge[RunStatus.Success]} />
)}
{runHistory.Status === RunStatus.Failed && (
<Badge {...statusValueBadge[RunStatus.Failed]} />
)}
</Col>
</Row>
);
};
导出
在这里插入代码片
export const RunningTaskList: React.FC = () => {
const { data, refresh, mutate } = useRequest(RunService.ListUserScriptRun);
console.log('useRequest(RunService.ListUserScriptRun)',useRequest(RunService.ListUserScriptRun));
useEffect(() => {
const timmer = window.setInterval(() => {
if (getWorkspaceId()) {
refresh();
}
}, 10_000);
return () => window.clearInterval(timmer);
}, [getWorkspaceId(), refresh]);
const { TabPane } = Tabs;
const content = (
<Tabs className={styles.tabs} defaultActiveKey="1" style={{ width: 500 }}>
<TabPane tab="进行中" key="1">
{data?.RunningScripts?.map((row, index) => (
<TaskDetail
key={row.Id}
row={row}
stopCB={() => {
data.RunningScripts[index].Status = RunStatus.Failed;
mutate({
...data,
});
}}
/>
))}
</TabPane>
<TabPane tab="已完成" key="2">
{data?.RecentFinished?.map((row) => (
<TaskDetail row={row} key={row.Id} />
))}
</TabPane>
</Tabs>
);
return (
<span style={{ paddingRight: '8px' }}>
<Badge count={data?.RunningScripts?.length || 0} style={{ background: '#1890ff' }}>
<Popover
placement="bottomRight"
content={content}
overlayClassName={styles.popup}
trigger="click"
>
<Button size="small" className={styles.TaskCountBtn}>
<UnorderedListOutlined />
</Button>
</Popover>
</Badge>
</span>
);
};
全部代码
import { SingleLineWrap } from '@/components/SingleLineWrap';
import { RunsPath, StrategyBacktestPath } from '@/constants/paths';
import { DevMode } from '@/enums/DevMode';
import { RunMode } from '@/enums/RunMode';
import { RunStatus } from '@/enums/RunStatus';
import { statusValueBadge } from '@/enums/StatusValueBadge';
import { RunService } from '@/services/Run/RunService';
import type { RunHistory } from '@/typings/RunHistory';
import { getWorkspaceId } from '@/utils/url';
import { useTaskDuration } from '@/utils/useTaskDuration';
import { history, useRequest } from '@alipay/bigfish';
import { Badge, Button, message, Popconfirm, Popover, Tabs, Tag } from '@alipay/bigfish/antd';
import { LoadingOutlined, UnorderedListOutlined } from '@alipay/bigfish/icons';
import { CloseOutlined } from '@alipay/tech-ui/icons';
import { Col, Row } from 'antd';
import CX from 'classnames';
import React, { useEffect } from 'react';
import styles from './index.less';
const getRunHistoryTypeName = (row: RunHistory) => {
switch (row.DevMode) {
default:
if (row.RunMode === RunMode.ROUNDED) {
return '完整运行';
} else {
return '调试运行';
}
case DevMode.Strategy:
if (row.RunMode === RunMode.ROUNDED) {
return '回测';
} else {
return '调试运行';
}
}
};
const onDetailClick = (row: RunHistory) => {
if (row.RunMode === RunMode.DEBUG) {
return;
}
switch (row.DevMode) {
case DevMode.DataScript:
case DevMode.Standard:
case DevMode.Free:
history.push(RunsPath(row.Id));
break;
case DevMode.Strategy:
history.push(StrategyBacktestPath(row.ScriptCode, row.Id));
}
};
const TaskDetail = (props: { row: RunHistory; stopCB?: CallableFunction }) => {
const runHistory = props.row;
const durationText = useTaskDuration(runHistory);
return (
<Row
className={CX([styles.row, runHistory.RunMode === RunMode.DEBUG && styles.clickable])}
onClick={() => onDetailClick(runHistory)}
align={'middle'}
justify={'space-between'}
>
<Col style={{ display: 'flex' }}>
<Tag color={runHistory.RunMode === RunMode.ROUNDED ? 'blue' : 'magenta'}>
{getRunHistoryTypeName(runHistory)}
</Tag>
<SingleLineWrap title={runHistory.Name} width={150} />
</Col>
<Col style={{ display: 'flex', alignItems: 'center' }}>
{runHistory.Status === RunStatus.Running && (
<>
<LoadingOutlined style={{ color: '#1890ff', marginRight: 8 }} />
<span style={{ color: '#1890ff' }}>{durationText}</span>
<Popconfirm
okText={'确认'}
cancelText={'取消'}
onConfirm={() => {
RunService.StopRun(runHistory.Id).then(() => {
message.success('终止运行成功');
props.stopCB?.();
});
}}
title={'您确定要终止运行任务吗?这个操作一旦执行就不能撤回。'}
>
<Button
type={'text'}
className={styles.hoverButton}
danger
onClick={(event) => event.stopPropagation()}
icon={<CloseOutlined />}
/>
</Popconfirm>
</>
)}
{runHistory.Status === RunStatus.Success && (
<Badge {...statusValueBadge[RunStatus.Success]} />
)}
{runHistory.Status === RunStatus.Failed && (
<Badge {...statusValueBadge[RunStatus.Failed]} />
)}
</Col>
</Row>
);
};
export const RunningTaskList: React.FC = () => {
const { data, refresh, mutate } = useRequest(RunService.ListUserScriptRun);
console.log('useRequest(RunService.ListUserScriptRun)',useRequest(RunService.ListUserScriptRun));
useEffect(() => {
const timmer = window.setInterval(() => {
if (getWorkspaceId()) {
refresh();
}
}, 10_000);
return () => window.clearInterval(timmer);
}, [getWorkspaceId(), refresh]);
const { TabPane } = Tabs;
const content = (
<Tabs className={styles.tabs} defaultActiveKey="1" style={{ width: 500 }}>
<TabPane tab="进行中" key="1">
{data?.RunningScripts?.map((row, index) => (
<TaskDetail
key={row.Id}
row={row}
stopCB={() => {
data.RunningScripts[index].Status = RunStatus.Failed;
mutate({
...data,
});
}}
/>
))}
</TabPane>
<TabPane tab="已完成" key="2">
{data?.RecentFinished?.map((row) => (
<TaskDetail row={row} key={row.Id} />
))}
</TabPane>
</Tabs>
);
return (
<span style={{ paddingRight: '8px' }}>
<Badge count={data?.RunningScripts?.length || 0} style={{ background: '#1890ff' }}>
<Popover
placement="bottomRight"
content={content}
overlayClassName={styles.popup}
trigger="click"
>
<Button size="small" className={styles.TaskCountBtn}>
<UnorderedListOutlined />
</Button>
</Popover>
</Badge>
</span>
);
};