diff --git a/back/interface/schedule.ts b/back/interface/schedule.ts new file mode 100644 index 00000000..8e9b98a5 --- /dev/null +++ b/back/interface/schedule.ts @@ -0,0 +1,13 @@ +export enum ScheduleType { + BOOT = '@boot', + ONCE = '@once', +} + +export type ScheduleValidator = (schedule?: string) => boolean; +export type CronSchedulerPayload = { + name: string; + id: string; + schedule: string; + command: string; + extra_schedules: Array<{ schedule: string }>; +}; diff --git a/back/services/cron.ts b/back/services/cron.ts index e5012486..2a625be2 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -22,6 +22,7 @@ import dayjs from 'dayjs'; import pickBy from 'lodash/pickBy'; import omit from 'lodash/omit'; import { writeFileWithLock } from '../shared/utils'; +import { ScheduleType } from '../interface/schedule'; @Service() export default class CronService { @@ -36,11 +37,11 @@ export default class CronService { } private isOnceSchedule(schedule?: string) { - return schedule?.startsWith('@once'); + return schedule?.startsWith(ScheduleType.ONCE); } private isBootSchedule(schedule?: string) { - return schedule?.startsWith('@boot'); + return schedule?.startsWith(ScheduleType.BOOT); } private isSpecialSchedule(schedule?: string) { diff --git a/back/validation/schedule.ts b/back/validation/schedule.ts index 76822941..a280156a 100644 --- a/back/validation/schedule.ts +++ b/back/validation/schedule.ts @@ -1,8 +1,12 @@ import { Joi } from 'celebrate'; import cron_parser from 'cron-parser'; +import { ScheduleType } from '../interface/schedule'; const validateSchedule = (value: string, helpers: any) => { - if (value.startsWith('@once') || value.startsWith('@boot')) { + if ( + value.startsWith(ScheduleType.ONCE) || + value.startsWith(ScheduleType.BOOT) + ) { return value; } diff --git a/src/pages/crontab/const.ts b/src/pages/crontab/const.ts new file mode 100644 index 00000000..ea8e2e04 --- /dev/null +++ b/src/pages/crontab/const.ts @@ -0,0 +1,13 @@ +import { ScheduleType } from './type'; + +export const scheduleTypeMap = { + [ScheduleType.Normal]: '', + [ScheduleType.Once]: '@once', + [ScheduleType.Boot]: '@boot', +}; + +export const getScheduleType = (schedule?: string): ScheduleType => { + if (schedule?.startsWith('@once')) return ScheduleType.Once; + if (schedule?.startsWith('@boot')) return ScheduleType.Boot; + return ScheduleType.Normal; +}; diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 75f4a7ce..5f81c517 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -1,64 +1,64 @@ -import intl from 'react-intl-universal'; -import React, { useState, useEffect, useRef, useMemo } from 'react'; +import useTableScrollHeight from '@/hooks/useTableScrollHeight'; +import { SharedContext } from '@/layouts'; +import { getCommandScript, getCrontabsNextDate } from '@/utils'; +import config from '@/utils/config'; +import { diffTime } from '@/utils/date'; +import { request } from '@/utils/http'; +import { + CheckCircleOutlined, + CheckOutlined, + ClockCircleOutlined, + CloseCircleOutlined, + CopyOutlined, + DeleteOutlined, + DownOutlined, + EditOutlined, + EllipsisOutlined, + FieldTimeOutlined, + Loading3QuartersOutlined, + PlusOutlined, + PushpinOutlined, + SettingOutlined, + StopOutlined, + UnorderedListOutlined +} from '@ant-design/icons'; +import { PageContainer } from '@ant-design/pro-layout'; +import { history, useOutletContext } from '@umijs/max'; import { Button, + Dropdown, + Input, + MenuProps, message, Modal, - Table, - Tag, Space, - Tooltip, - Dropdown, - Menu, - Typography, - Input, - Popover, - Tabs, + Table, TablePaginationConfig, - MenuProps, + Tabs, + Tag, + Typography } from 'antd'; -import { - ClockCircleOutlined, - Loading3QuartersOutlined, - CloseCircleOutlined, - FileTextOutlined, - EllipsisOutlined, - PlayCircleOutlined, - CheckCircleOutlined, - EditOutlined, - StopOutlined, - DeleteOutlined, - PauseCircleOutlined, - FieldTimeOutlined, - PushpinOutlined, - DownOutlined, - SettingOutlined, - PlusOutlined, - UnorderedListOutlined, - CheckOutlined, - CopyOutlined, -} from '@ant-design/icons'; -import config from '@/utils/config'; -import { PageContainer } from '@ant-design/pro-layout'; -import { request } from '@/utils/http'; -import CronModal, { CronLabelModal } from './modal'; -import CronLogModal from './logModal'; -import CronDetailModal from './detail'; -import { diffTime } from '@/utils/date'; -import { history, useOutletContext } from '@umijs/max'; -import './index.less'; -import ViewCreateModal from './viewCreateModal'; -import ViewManageModal from './viewManageModal'; -import { FilterValue, SorterResult } from 'antd/lib/table/interface'; -import { SharedContext } from '@/layouts'; -import useTableScrollHeight from '@/hooks/useTableScrollHeight'; -import { getCommandScript, getCrontabsNextDate, parseCrontab } from '@/utils'; import { ColumnProps } from 'antd/lib/table'; -import { useVT } from 'virtualizedtableforantd4'; -import { ICrontab, OperationName, OperationPath, CrontabStatus } from './type'; -import Name from '@/components/name'; +import { FilterValue, SorterResult } from 'antd/lib/table/interface'; import dayjs from 'dayjs'; import { noop, omit } from 'lodash'; +import React, { useEffect, useRef, useState } from 'react'; +import intl from 'react-intl-universal'; +import { useVT } from 'virtualizedtableforantd4'; +import { getScheduleType } from './const'; +import CronDetailModal from './detail'; +import './index.less'; +import CronLogModal from './logModal'; +import CronModal, { CronLabelModal } from './modal'; +import { + CrontabStatus, + ICrontab, + OperationName, + OperationPath, + ScheduleType, +} from './type'; +import ViewCreateModal from './viewCreateModal'; +import ViewManageModal from './viewManageModal'; const { Text, Paragraph, Link } = Typography; const { Search } = Input; @@ -263,7 +263,7 @@ const Crontab = () => { }, }, render: (text, record) => { - return record.nextRunTime + return record.nextRunTime ? dayjs(record.nextRunTime).format('YYYY-MM-DD HH:mm:ss') : '-'; }, @@ -398,10 +398,11 @@ const Crontab = () => { setValue( data.map((x) => { - const specialSchedules = ['@once', '@boot']; - const nextRunTime = specialSchedules.includes(x.schedule) - ? null - : getCrontabsNextDate(x.schedule, x.extra_schedules); + const scheduleType = getScheduleType(x.schedule); + const nextRunTime = + scheduleType === ScheduleType.Normal + ? getCrontabsNextDate(x.schedule, x.extra_schedules) + : null; return { ...x, nextRunTime, @@ -812,7 +813,9 @@ const Crontab = () => { useEffect(() => { if (viewConf && enabledCronViews && enabledCronViews.length > 0) { - const view = enabledCronViews.slice(SHOW_TAB_COUNT).find((x) => x.id === viewConf.id); + const view = enabledCronViews + .slice(SHOW_TAB_COUNT) + .find((x) => x.id === viewConf.id); setMoreMenuActive(!!view); } }, [viewConf, enabledCronViews]); diff --git a/src/pages/crontab/modal.tsx b/src/pages/crontab/modal.tsx index 0faeb42a..2215cc54 100644 --- a/src/pages/crontab/modal.tsx +++ b/src/pages/crontab/modal.tsx @@ -1,29 +1,13 @@ -import intl from 'react-intl-universal'; -import React, { useEffect, useState } from 'react'; -import { Modal, message, Input, Form, Button, Space, Select } from 'antd'; -import { request } from '@/utils/http'; -import config from '@/utils/config'; -import cronParse from 'cron-parser'; import EditableTagGroup from '@/components/tag'; +import config from '@/utils/config'; +import { request } from '@/utils/http'; import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; - -enum ScheduleType { - Normal = 'normal', - Once = 'once', - Boot = 'boot', -} - -const scheduleTypeMap = { - [ScheduleType.Normal]: '', - [ScheduleType.Once]: '@once', - [ScheduleType.Boot]: '@boot', -}; - -const getScheduleType = (schedule?: string): ScheduleType => { - if (schedule?.startsWith('@once')) return ScheduleType.Once; - if (schedule?.startsWith('@boot')) return ScheduleType.Boot; - return ScheduleType.Normal; -}; +import { Button, Form, Input, Modal, Select, Space, message } from 'antd'; +import cronParse from 'cron-parser'; +import { useEffect, useState } from 'react'; +import intl from 'react-intl-universal'; +import { getScheduleType, scheduleTypeMap } from './const'; +import { ScheduleType } from './type'; const CronModal = ({ cron, @@ -85,7 +69,11 @@ const CronModal = ({ }; const renderScheduleOptions = () => ( - {intl.get('常规定时')} @@ -336,4 +324,5 @@ const CronLabelModal = ({ ); }; -export { CronModal as default, CronLabelModal }; +export { CronLabelModal, CronModal as default }; + diff --git a/src/pages/crontab/type.ts b/src/pages/crontab/type.ts index dcb6459e..890eaef8 100644 --- a/src/pages/crontab/type.ts +++ b/src/pages/crontab/type.ts @@ -36,5 +36,11 @@ export interface ICrontab { last_execution_time?: number; nextRunTime: Date; sub_id: number; - extra_schedules?: Array<{ schedule: string; }>; + extra_schedules?: Array<{ schedule: string }>; +} + +export enum ScheduleType { + Normal = 'normal', + Once = 'once', + Boot = 'boot', }