mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-23 23:06:06 +08:00
任务详情增加运行、禁用、置顶操作
This commit is contained in:
parent
1b893f35ba
commit
8bb8a29400
7
src/components/iconfont.tsx
Normal file
7
src/components/iconfont.tsx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { createFromIconfontCN } from '@ant-design/icons';
|
||||||
|
|
||||||
|
const IconFont = createFromIconfontCN({
|
||||||
|
scriptUrl: ['//at.alicdn.com/t/font_3354854_pk18p04ny1a.js'],
|
||||||
|
});
|
||||||
|
|
||||||
|
export default IconFont;
|
|
@ -10,6 +10,7 @@ import {
|
||||||
List,
|
List,
|
||||||
Divider,
|
Divider,
|
||||||
Typography,
|
Typography,
|
||||||
|
Tooltip,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import {
|
import {
|
||||||
ClockCircleOutlined,
|
ClockCircleOutlined,
|
||||||
|
@ -17,6 +18,8 @@ import {
|
||||||
FieldTimeOutlined,
|
FieldTimeOutlined,
|
||||||
Loading3QuartersOutlined,
|
Loading3QuartersOutlined,
|
||||||
FileOutlined,
|
FileOutlined,
|
||||||
|
PlayCircleOutlined,
|
||||||
|
PauseCircleOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { CrontabStatus } from './index';
|
import { CrontabStatus } from './index';
|
||||||
import { diffTime } from '@/utils/date';
|
import { diffTime } from '@/utils/date';
|
||||||
|
@ -24,6 +27,7 @@ import { request } from '@/utils/http';
|
||||||
import config from '@/utils/config';
|
import config from '@/utils/config';
|
||||||
import CronLogModal from './logModal';
|
import CronLogModal from './logModal';
|
||||||
import Editor from '@monaco-editor/react';
|
import Editor from '@monaco-editor/react';
|
||||||
|
import IconFont from '@/components/iconfont';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
@ -68,6 +72,7 @@ const CronDetailModal = ({
|
||||||
const [scriptInfo, setScriptInfo] = useState<any>({});
|
const [scriptInfo, setScriptInfo] = useState<any>({});
|
||||||
const [logUrl, setLogUrl] = useState('');
|
const [logUrl, setLogUrl] = useState('');
|
||||||
const [validTabs, setValidTabs] = useState(tabList);
|
const [validTabs, setValidTabs] = useState(tabList);
|
||||||
|
const [currentCron, setCurrentCron] = useState<any>({});
|
||||||
|
|
||||||
const contentList: any = {
|
const contentList: any = {
|
||||||
log: (
|
log: (
|
||||||
|
@ -103,7 +108,7 @@ const CronDetailModal = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClickItem = (item: LogItem) => {
|
const onClickItem = (item: LogItem) => {
|
||||||
localStorage.setItem('logCron', cron.id);
|
localStorage.setItem('logCron', currentCron.id);
|
||||||
setLogUrl(`${config.apiPrefix}logs/${item.directory}/${item.filename}`);
|
setLogUrl(`${config.apiPrefix}logs/${item.directory}/${item.filename}`);
|
||||||
request
|
request
|
||||||
.get(`${config.apiPrefix}logs/${item.directory}/${item.filename}`)
|
.get(`${config.apiPrefix}logs/${item.directory}/${item.filename}`)
|
||||||
|
@ -196,8 +201,150 @@ const CronDetailModal = ({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const runCron = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认运行',
|
||||||
|
content: (
|
||||||
|
<>
|
||||||
|
确认运行定时任务{' '}
|
||||||
|
<Text style={{ wordBreak: 'break-all' }} type="warning">
|
||||||
|
{currentCron.name}
|
||||||
|
</Text>{' '}
|
||||||
|
吗
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
onOk() {
|
||||||
|
request
|
||||||
|
.put(`${config.apiPrefix}crons/run`, { data: [currentCron.id] })
|
||||||
|
.then((data: any) => {
|
||||||
|
if (data.code === 200) {
|
||||||
|
setCurrentCron({ ...currentCron, status: CrontabStatus.running });
|
||||||
|
setTimeout(() => {
|
||||||
|
getLogs();
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
message.error(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
console.log('Cancel');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopCron = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认停止',
|
||||||
|
content: (
|
||||||
|
<>
|
||||||
|
确认停止定时任务{' '}
|
||||||
|
<Text style={{ wordBreak: 'break-all' }} type="warning">
|
||||||
|
{currentCron.name}
|
||||||
|
</Text>{' '}
|
||||||
|
吗
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
onOk() {
|
||||||
|
request
|
||||||
|
.put(`${config.apiPrefix}crons/stop`, { data: [currentCron.id] })
|
||||||
|
.then((data: any) => {
|
||||||
|
if (data.code === 200) {
|
||||||
|
setCurrentCron({ ...currentCron, status: CrontabStatus.idle });
|
||||||
|
} else {
|
||||||
|
message.error(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
console.log('Cancel');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const enabledOrDisabledCron = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: `确认${currentCron.isDisabled === 1 ? '启用' : '禁用'}`,
|
||||||
|
content: (
|
||||||
|
<>
|
||||||
|
确认{currentCron.isDisabled === 1 ? '启用' : '禁用'}
|
||||||
|
定时任务{' '}
|
||||||
|
<Text style={{ wordBreak: 'break-all' }} type="warning">
|
||||||
|
{currentCron.name}
|
||||||
|
</Text>{' '}
|
||||||
|
吗
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
onOk() {
|
||||||
|
request
|
||||||
|
.put(
|
||||||
|
`${config.apiPrefix}crons/${
|
||||||
|
currentCron.isDisabled === 1 ? 'enable' : 'disable'
|
||||||
|
}`,
|
||||||
|
{
|
||||||
|
data: [currentCron.id],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then((data: any) => {
|
||||||
|
if (data.code === 200) {
|
||||||
|
setCurrentCron({
|
||||||
|
...currentCron,
|
||||||
|
isDisabled: currentCron.isDisabled === 1 ? 0 : 1,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.error(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
console.log('Cancel');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const pinOrUnPinCron = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: `确认${currentCron.isPinned === 1 ? '取消置顶' : '置顶'}`,
|
||||||
|
content: (
|
||||||
|
<>
|
||||||
|
确认{currentCron.isPinned === 1 ? '取消置顶' : '置顶'}
|
||||||
|
定时任务{' '}
|
||||||
|
<Text style={{ wordBreak: 'break-all' }} type="warning">
|
||||||
|
{currentCron.name}
|
||||||
|
</Text>{' '}
|
||||||
|
吗
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
onOk() {
|
||||||
|
request
|
||||||
|
.put(
|
||||||
|
`${config.apiPrefix}crons/${
|
||||||
|
currentCron.isPinned === 1 ? 'unpin' : 'pin'
|
||||||
|
}`,
|
||||||
|
{
|
||||||
|
data: [currentCron.id],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then((data: any) => {
|
||||||
|
if (data.code === 200) {
|
||||||
|
setCurrentCron({
|
||||||
|
...currentCron,
|
||||||
|
isPinned: currentCron.isPinned === 1 ? 0 : 1,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.error(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
console.log('Cancel');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cron && cron.id) {
|
if (cron && cron.id) {
|
||||||
|
setCurrentCron(cron);
|
||||||
getLogs();
|
getLogs();
|
||||||
getScript();
|
getScript();
|
||||||
}
|
}
|
||||||
|
@ -206,19 +353,76 @@ const CronDetailModal = ({
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={
|
title={
|
||||||
<>
|
<div className="crontab-title-wrapper">
|
||||||
<span>{cron.name}</span>
|
<div>
|
||||||
{cron.labels?.length > 0 && cron.labels[0] !== '' && (
|
<span>{currentCron.name}</span>
|
||||||
<Divider type="vertical"></Divider>
|
{currentCron.labels?.length > 0 && currentCron.labels[0] !== '' && (
|
||||||
)}
|
<Divider type="vertical"></Divider>
|
||||||
{cron.labels?.length > 0 &&
|
)}
|
||||||
cron.labels[0] !== '' &&
|
{currentCron.labels?.length > 0 &&
|
||||||
cron.labels?.map((label: string, i: number) => (
|
currentCron.labels[0] !== '' &&
|
||||||
<Tag color="blue" style={{ marginRight: 5 }}>
|
currentCron.labels?.map((label: string, i: number) => (
|
||||||
{label}
|
<Tag color="blue" style={{ marginRight: 5 }}>
|
||||||
</Tag>
|
{label}
|
||||||
))}
|
</Tag>
|
||||||
</>
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="operations">
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
currentCron.status === CrontabStatus.idle ? '运行' : '停止'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={
|
||||||
|
currentCron.status === CrontabStatus.idle ? (
|
||||||
|
<PlayCircleOutlined />
|
||||||
|
) : (
|
||||||
|
<PauseCircleOutlined />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
size="small"
|
||||||
|
onClick={
|
||||||
|
currentCron.status === CrontabStatus.idle ? runCron : stopCron
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip title={currentCron.isDisabled === 1 ? '启用' : '禁用'}>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={
|
||||||
|
<IconFont
|
||||||
|
type={
|
||||||
|
currentCron.isDisabled === 1
|
||||||
|
? 'ql-icon-qiyong'
|
||||||
|
: 'ql-icon-jinyong'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
size="small"
|
||||||
|
onClick={enabledOrDisabledCron}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip title={currentCron.isPinned === 1 ? '取消置顶' : '置顶'}>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={
|
||||||
|
<IconFont
|
||||||
|
type={
|
||||||
|
currentCron.isPinned === 1
|
||||||
|
? 'ql-icon-quxiaozhiding'
|
||||||
|
: 'ql-icon-zhiding'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
size="small"
|
||||||
|
onClick={pinOrUnPinCron}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
centered
|
centered
|
||||||
visible={visible}
|
visible={visible}
|
||||||
|
@ -232,21 +436,22 @@ const CronDetailModal = ({
|
||||||
<Card>
|
<Card>
|
||||||
<div className="cron-detail-info-item">
|
<div className="cron-detail-info-item">
|
||||||
<div className="cron-detail-info-title">任务</div>
|
<div className="cron-detail-info-title">任务</div>
|
||||||
<div className="cron-detail-info-value">{cron.command}</div>
|
<div className="cron-detail-info-value">{currentCron.command}</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
<Card style={{ marginTop: 10 }}>
|
<Card style={{ marginTop: 10 }}>
|
||||||
<div className="cron-detail-info-item">
|
<div className="cron-detail-info-item">
|
||||||
<div className="cron-detail-info-title">状态</div>
|
<div className="cron-detail-info-title">状态</div>
|
||||||
<div className="cron-detail-info-value">
|
<div className="cron-detail-info-value">
|
||||||
{(!cron.isDisabled || cron.status !== CrontabStatus.idle) && (
|
{(!currentCron.isDisabled ||
|
||||||
|
currentCron.status !== CrontabStatus.idle) && (
|
||||||
<>
|
<>
|
||||||
{cron.status === CrontabStatus.idle && (
|
{currentCron.status === CrontabStatus.idle && (
|
||||||
<Tag icon={<ClockCircleOutlined />} color="default">
|
<Tag icon={<ClockCircleOutlined />} color="default">
|
||||||
空闲中
|
空闲中
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
{cron.status === CrontabStatus.running && (
|
{currentCron.status === CrontabStatus.running && (
|
||||||
<Tag
|
<Tag
|
||||||
icon={<Loading3QuartersOutlined spin />}
|
icon={<Loading3QuartersOutlined spin />}
|
||||||
color="processing"
|
color="processing"
|
||||||
|
@ -254,29 +459,30 @@ const CronDetailModal = ({
|
||||||
运行中
|
运行中
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
{cron.status === CrontabStatus.queued && (
|
{currentCron.status === CrontabStatus.queued && (
|
||||||
<Tag icon={<FieldTimeOutlined />} color="default">
|
<Tag icon={<FieldTimeOutlined />} color="default">
|
||||||
队列中
|
队列中
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{cron.isDisabled === 1 && cron.status === CrontabStatus.idle && (
|
{currentCron.isDisabled === 1 &&
|
||||||
<Tag icon={<CloseCircleOutlined />} color="error">
|
currentCron.status === CrontabStatus.idle && (
|
||||||
已禁用
|
<Tag icon={<CloseCircleOutlined />} color="error">
|
||||||
</Tag>
|
已禁用
|
||||||
)}
|
</Tag>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="cron-detail-info-item">
|
<div className="cron-detail-info-item">
|
||||||
<div className="cron-detail-info-title">定时</div>
|
<div className="cron-detail-info-title">定时</div>
|
||||||
<div className="cron-detail-info-value">{cron.schedule}</div>
|
<div className="cron-detail-info-value">{currentCron.schedule}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="cron-detail-info-item">
|
<div className="cron-detail-info-item">
|
||||||
<div className="cron-detail-info-title">最后运行时间</div>
|
<div className="cron-detail-info-title">最后运行时间</div>
|
||||||
<div className="cron-detail-info-value">
|
<div className="cron-detail-info-value">
|
||||||
{cron.last_execution_time
|
{currentCron.last_execution_time
|
||||||
? new Date(cron.last_execution_time * 1000)
|
? new Date(currentCron.last_execution_time * 1000)
|
||||||
.toLocaleString(language, {
|
.toLocaleString(language, {
|
||||||
hour12: false,
|
hour12: false,
|
||||||
})
|
})
|
||||||
|
@ -287,14 +493,16 @@ const CronDetailModal = ({
|
||||||
<div className="cron-detail-info-item">
|
<div className="cron-detail-info-item">
|
||||||
<div className="cron-detail-info-title">最后运行时长</div>
|
<div className="cron-detail-info-title">最后运行时长</div>
|
||||||
<div className="cron-detail-info-value">
|
<div className="cron-detail-info-value">
|
||||||
{cron.last_running_time ? diffTime(cron.last_running_time) : '-'}
|
{currentCron.last_running_time
|
||||||
|
? diffTime(currentCron.last_running_time)
|
||||||
|
: '-'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="cron-detail-info-item">
|
<div className="cron-detail-info-item">
|
||||||
<div className="cron-detail-info-title">下次运行时间</div>
|
<div className="cron-detail-info-title">下次运行时间</div>
|
||||||
<div className="cron-detail-info-value">
|
<div className="cron-detail-info-value">
|
||||||
{cron.nextRunTime &&
|
{currentCron.nextRunTime &&
|
||||||
cron.nextRunTime
|
currentCron.nextRunTime
|
||||||
.toLocaleString(language, {
|
.toLocaleString(language, {
|
||||||
hour12: false,
|
hour12: false,
|
||||||
})
|
})
|
||||||
|
|
|
@ -77,6 +77,22 @@
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.crontab-title-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-right: 32px;
|
||||||
|
|
||||||
|
.operations {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.ant-btn:not(:first-child) {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-item {
|
.log-item {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user