From aa08f489d7f09883573bcbb6ad61a22c7ffc095f Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 19 Sep 2021 22:25:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=BD=AE=E9=A1=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/cron.ts | 36 +++++++++++++++ back/services/cron.ts | 26 +++++++++++ src/pages/crontab/index.tsx | 92 ++++++++++++++++++++++++++++++++++++- 3 files changed, 152 insertions(+), 2 deletions(-) diff --git a/back/api/cron.ts b/back/api/cron.ts index a4374047..75b46150 100644 --- a/back/api/cron.ts +++ b/back/api/cron.ts @@ -191,6 +191,42 @@ export default (app: Router) => { }, ); + route.put( + '/crons/pin', + celebrate({ + body: Joi.array().items(Joi.string().required()), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const cronService = Container.get(CronService); + const data = await cronService.pin(req.body); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.put( + '/crons/unpin', + celebrate({ + body: Joi.array().items(Joi.string().required()), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const cronService = Container.get(CronService); + const data = await cronService.unPin(req.body); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + route.get( '/crons/import', async (req: Request, res: Response, next: NextFunction) => { diff --git a/back/services/cron.ts b/back/services/cron.ts index 01b483d2..b1b68564 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -115,6 +115,32 @@ export default class CronService { }); } + public async pin(ids: string[]) { + return new Promise((resolve: any) => { + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { isPinned: 1 } }, + { multi: true }, + async (err) => { + resolve(); + }, + ); + }); + } + + public async unPin(ids: string[]) { + return new Promise((resolve: any) => { + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { isPinned: 0 } }, + { multi: true }, + async (err) => { + resolve(); + }, + ); + }); + } + public async crontabs(searchText?: string): Promise { let query = {}; if (searchText) { diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 71312ecf..dcd8d22d 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -25,6 +25,7 @@ import { DeleteOutlined, PauseCircleOutlined, FieldTimeOutlined, + PushpinOutlined, } from '@ant-design/icons'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; @@ -49,6 +50,8 @@ enum OperationName { '禁用', '运行', '停止', + '置顶', + '取消置顶', } enum OperationPath { @@ -56,6 +59,8 @@ enum OperationPath { 'disable', 'run', 'stop', + 'pin', + 'unpin', } const Crontab = ({ headerStyle, isPhone }: any) => { @@ -66,7 +71,16 @@ const Crontab = ({ headerStyle, isPhone }: any) => { key: 'name', align: 'center' as const, render: (text: string, record: any) => ( - {record.name || record._id} + + {record.name || record._id}{' '} + {record.isPinned ? ( + + + + ) : ( + '' + )} + ), sorter: { compare: (a: any, b: any) => a.name.localeCompare(b.name), @@ -237,7 +251,12 @@ const Crontab = ({ headerStyle, isPhone }: any) => { data.data.sort((a: any, b: any) => { const sortA = a.isDisabled ? 4 : a.status; const sortB = b.isDisabled ? 4 : b.status; - return CrontabSort[sortA] - CrontabSort[sortB]; + a.isPinned = a.isPinned ? a.isPinned : 0; + b.isPinned = b.isPinned ? b.isPinned : 0; + if (a.isPinned === b.isPinned) { + return CrontabSort[sortA] - CrontabSort[sortB]; + } + return b.isPinned - a.isPinned; }), ); setCurrentPage(1); @@ -403,6 +422,50 @@ const Crontab = ({ headerStyle, isPhone }: any) => { }); }; + const pinOrunPinCron = (record: any, index: number) => { + Modal.confirm({ + title: `确认${record.isPinned === 1 ? '取消置顶' : '置顶'}`, + content: ( + <> + 确认{record.isPinned === 1 ? '取消置顶' : '置顶'} + 定时任务{' '} + + {record.name} + {' '} + 吗 + + ), + onOk() { + request + .put( + `${config.apiPrefix}crons/${ + record.isPinned === 1 ? 'unpin' : 'pin' + }`, + { + data: [record._id], + }, + ) + .then((data: any) => { + if (data.code === 200) { + const newStatus = record.isPinned === 1 ? 0 : 1; + const result = [...value]; + const i = result.findIndex((x) => x._id === record._id); + result.splice(i, 1, { + ...record, + isPinned: newStatus, + }); + setValue(result); + } else { + message.error(data); + } + }); + }, + onCancel() { + console.log('Cancel'); + }, + }); + }; + const MoreBtn: React.FC<{ record: any; index: number; @@ -432,6 +495,14 @@ const Crontab = ({ headerStyle, isPhone }: any) => { 删除 )} + : + } + > + {record.isPinned === 1 ? '取消置顶' : '置顶'} + } > @@ -452,6 +523,9 @@ const Crontab = ({ headerStyle, isPhone }: any) => { case 'delete': delCron(record, index); break; + case 'pinOrunPin': + pinOrunPinCron(record, index); + break; default: break; } @@ -626,6 +700,20 @@ const Crontab = ({ headerStyle, isPhone }: any) => { + + 已选择 {selectedRowIds?.length}