diff --git a/back/api/cron.ts b/back/api/cron.ts index 76a376b9..562a4275 100644 --- a/back/api/cron.ts +++ b/back/api/cron.ts @@ -28,8 +28,8 @@ export default (app: Router) => { celebrate({ body: Joi.object({ name: Joi.string().required(), - sorts: Joi.string().optional(), - filters: Joi.string().optional(), + sorts: Joi.array().optional(), + filters: Joi.array().optional(), }), }), async (req: Request, res: Response, next: NextFunction) => { @@ -49,8 +49,8 @@ export default (app: Router) => { body: Joi.object({ name: Joi.string().required(), id: Joi.number().required(), - sorts: Joi.string().optional(), - filters: Joi.string().optional(), + sorts: Joi.array().optional(), + filters: Joi.array().optional(), }), }), async (req: Request, res: Response, next: NextFunction) => { diff --git a/back/services/cron.ts b/back/services/cron.ts index 94625ce1..10abb155 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -14,7 +14,7 @@ import dayjs from 'dayjs'; @Service() export default class CronService { - constructor(@Inject('logger') private logger: winston.Logger) {} + constructor(@Inject('logger') private logger: winston.Logger) { } private isSixCron(cron: Crontab) { const { schedule } = cron; @@ -113,20 +113,34 @@ export default class CronService { } } - public async crontabs(params?: { - searchValue: string; - page: string; - size: string; - sortField: string; - sortType: string; - }): Promise<{ data: Crontab[]; total: number }> { - const searchText = params?.searchValue; - const page = Number(params?.page || '0'); - const size = Number(params?.size || '0'); - const sortField = params?.sortField || ''; - const sortType = params?.sortType || ''; + private formatViewQuery(query: any, viewQuery: any) { + if (viewQuery.filters) { + for (const col of viewQuery.filters) { + const { property, value, operation } = col; + let operate = null; + switch (operation) { + case 'Reg': + operate = Op.like; + break; + case 'Reg': + operate = Op.notLike; + break; + default: + break; + } + if (operate) { + query[property] = { + [Op.or]: [ + { [operate]: `%${value}%` }, + { [operate]: `%${encodeURIComponent(value)}%` }, + ], + } + } + } + } + } - let query = {}; + private formatSearchText(query: any, searchText: string | undefined) { if (searchText) { const textArray = searchText.split(':'); switch (textArray[0]) { @@ -170,12 +184,43 @@ export default class CronService { break; } } + } + + private formatViewSort(order: string[][], viewQuery: any) { + if (viewQuery.sorts) { + for (const [col, sortType] of viewQuery.sorts) { + order.unshift([col, sortType]); + } + } + } + + public async crontabs(params?: { + searchValue: string; + page: string; + size: string; + sortField: string; + sortType: string; + queryString: string; + }): Promise<{ data: Crontab[]; total: number }> { + const searchText = params?.searchValue; + const page = Number(params?.page || '0'); + const size = Number(params?.size || '0'); + const sortField = params?.sortField || ''; + const sortType = params?.sortType || ''; + const viewQuery = JSON.parse(params?.queryString || '{}'); + + let query: any = {}; let order = [ ['isPinned', 'DESC'], ['isDisabled', 'ASC'], ['status', 'ASC'], ['createdAt', 'DESC'], ]; + + this.formatViewQuery(query, viewQuery); + this.formatSearchText(query, searchText); + this.formatViewSort(order, viewQuery); + if (sortType && sortField) { order.unshift([sortField, sortType]); } @@ -229,9 +274,9 @@ export default class CronService { const endTime = dayjs(); const diffTimeStr = doc.last_execution_time ? `,耗时 ${endTime.diff( - dayjs(doc.last_execution_time * 1000), - 'second', - )}` + dayjs(doc.last_execution_time * 1000), + 'second', + )}` : ''; if (logFileExist) { const str = err ? `\n${err}` : ''; diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index f9957c20..b37f7a43 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -186,9 +186,8 @@ export default function (props: any) { if ( ['/login', '/initialization', '/error'].includes(props.location.pathname) ) { - document.title = `${ - (config.documentTitleMap as any)[props.location.pathname] - } - 控制面板`; + document.title = `${(config.documentTitleMap as any)[props.location.pathname] + } - 控制面板`; if ( systemInfo?.isInitialized && props.location.pathname === '/initialization' @@ -282,7 +281,7 @@ export default function (props: any) { shape="square" size="small" icon={} - src={`/api/static/${user.avatar}`} + src={user.avatar ? `/api/static/${user.avatar}` : ''} /> {user.username} @@ -304,7 +303,7 @@ export default function (props: any) { shape="square" size="small" icon={} - src={`/api/static/${user.avatar}`} + src={user.avatar ? `/api/static/${user.avatar}` : ''} /> {user.username} diff --git a/src/pages/crontab/index.less b/src/pages/crontab/index.less index 7365dc1b..747f55b1 100644 --- a/src/pages/crontab/index.less +++ b/src/pages/crontab/index.less @@ -108,7 +108,7 @@ } .view-more { - margin-left: 20px; + margin-left: 32px; padding: 8px 0; cursor: pointer; diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index e0a4fd3e..a934aecc 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -358,6 +358,7 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { size: number; sorter: any; }>({} as any); + const [viewConf, setViewConf] = useState(); const [tableScrollHeight, setTableScrollHeight] = useState(); const [isDetailModalVisible, setIsDetailModalVisible] = useState(false); const [detailCron, setDetailCron] = useState(); @@ -396,6 +397,9 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { sorter.order === 'ascend' ? 'ASC' : 'DESC' }`; } + if (viewConf) { + url += `&queryString=${JSON.stringify({ filters: viewConf.filters })}`; + } request .get(url) .then((_data: any) => { @@ -828,7 +832,7 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { if (pageConf.page && pageConf.size) { getCrons(); } - }, [pageConf]); + }, [pageConf, viewConf]); useEffect(() => { setPageConf({ @@ -944,6 +948,7 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { break; default: + tabClick(key); break; } }; @@ -955,7 +960,7 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { viewAction(key); }} items={[ - ...[...cronViews].slice(5).map((x) => ({ + ...[...cronViews].slice(2).map((x) => ({ label: x.name, key: x.id, icon: , @@ -989,6 +994,11 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { }); }; + const tabClick = (key: string) => { + const view = cronViews.find(x => x.id == key); + setViewConf(view ? view : null); + } + return ( { tabPosition="top" className="crontab-view" tabBarExtraContent={ - +
更多 @@ -1028,11 +1038,12 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
} + onTabClick={tabClick} > {panelContent} - {[...cronViews].slice(0, 5).map((x) => ( + {[...cronViews].slice(0, 2).map((x) => ( {panelContent} @@ -1073,14 +1084,19 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { { + getCronViews(); setIsCreateViewModalVisible(false); }} /> { setIsViewManageModalVisible(false); }} + cronViewChange={() => { + getCronViews(); + }} />
); diff --git a/src/pages/crontab/viewCreateModal.tsx b/src/pages/crontab/viewCreateModal.tsx index 5e93878d..c43e38e8 100644 --- a/src/pages/crontab/viewCreateModal.tsx +++ b/src/pages/crontab/viewCreateModal.tsx @@ -20,10 +20,14 @@ const PROPERTIES = [ ]; const OPERATIONS = [ - { name: '包含', value: 'contains' }, - { name: '不包含', value: 'noncontains' }, - // { name: '属于', value: 'belong' }, - // { name: '不属于', value: 'nonbelong' }, + { name: '包含', value: 'Reg' }, + { name: '不包含', value: 'NotReg' }, + // { name: '属于', value: 'In' }, + // { name: '不属于', value: 'Nin' }, + // { name: '等于', value: 'Eq' }, + // { name: '不等于', value: 'Ne' }, + // { name: '为空', value: 'IsNull' }, + // { name: '不为空', value: 'NotNull' }, ]; const ViewCreateModal = ({ @@ -61,7 +65,7 @@ const ViewCreateModal = ({ useEffect(() => { form.resetFields(); form.setFieldsValue({ - filters: [{ property: 'command', operation: 'contains' }], + filters: [{ property: 'command', operation: 'Reg' }], }); }, [view, visible]); @@ -154,9 +158,9 @@ const ViewCreateModal = ({ ))} - add({ property: 'command', operation: 'contains' }) + add({ property: 'command', operation: 'Reg' }) } > diff --git a/src/pages/crontab/viewManageModal.tsx b/src/pages/crontab/viewManageModal.tsx index 00a8a641..33d7fad4 100644 --- a/src/pages/crontab/viewManageModal.tsx +++ b/src/pages/crontab/viewManageModal.tsx @@ -3,8 +3,6 @@ import { Modal, message, Space, Table, Tag, Typography, Button } from 'antd'; import { request } from '@/utils/http'; import config from '@/utils/config'; import { DeleteOutlined, EditOutlined } from '@ant-design/icons'; -import { PageLoading } from '@ant-design/pro-layout'; -import Paragraph from 'antd/lib/skeleton/Paragraph'; import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import ViewCreateModal from './viewCreateModal'; @@ -58,11 +56,15 @@ const DragableBodyRow = ({ }; const ViewManageModal = ({ + cronViews, handleCancel, visible, + cronViewChange }: { + cronViews: any[]; visible: boolean; handleCancel: () => void; + cronViewChange: () => void; }) => { const columns: any = [ { @@ -72,16 +74,16 @@ const ViewManageModal = ({ align: 'center' as const, width: 70, }, - { - title: '显示', - key: 'status', - dataIndex: 'status', - align: 'center' as const, - width: 70, - render: (text: string, record: any, index: number) => { - return ; - }, - }, + // { + // title: '显示', + // key: 'isDisabled', + // dataIndex: 'isDisabled', + // align: 'center' as const, + // width: 70, + // render: (text: string, record: any, index: number) => { + // return ; + // }, + // }, { title: '操作', key: 'action', @@ -102,7 +104,6 @@ const ViewManageModal = ({ }, ]; const [list, setList] = useState([]); - const [loading, setLoading] = useState(true); const [isCreateViewModalVisible, setIsCreateViewModalVisible] = useState(false); @@ -129,9 +130,7 @@ const ViewManageModal = ({ .then((data: any) => { if (data.code === 200) { message.success('删除成功'); - const result = [...list]; - result.splice(index, 1); - setList(result); + cronViewChange(); } else { message.error(data); } @@ -143,18 +142,6 @@ const ViewManageModal = ({ }); }; - const getCronViews = () => { - setLoading(true); - request - .get(`${config.apiPrefix}crons/views`) - .then((data: any) => { - console.log(data); - }) - .finally(() => { - setLoading(false); - }); - }; - const components = { body: { row: DragableBodyRow, @@ -186,8 +173,8 @@ const ViewManageModal = ({ ); useEffect(() => { - // getCronViews(); - }, []); + setList(cronViews); + }, [cronViews]); return ( - +