From 419c5a7c5bcec686dec3cebc30374b71159bc817 Mon Sep 17 00:00:00 2001 From: whyour Date: Tue, 10 May 2022 19:54:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=AE=A2=E9=98=85api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/index.ts | 2 + back/api/subscription.ts | 278 ++++++++++++++++++++++++++++++++++ back/loaders/db.ts | 3 + back/services/subscription.ts | 56 +++++++ 4 files changed, 339 insertions(+) create mode 100644 back/api/subscription.ts diff --git a/back/api/index.ts b/back/api/index.ts index f616b91a..36c56599 100644 --- a/back/api/index.ts +++ b/back/api/index.ts @@ -8,6 +8,7 @@ import script from './script'; import open from './open'; import dependence from './dependence'; import system from './system'; +import subscription from './subscription'; export default () => { const app = Router(); @@ -20,6 +21,7 @@ export default () => { open(app); dependence(app); system(app); + subscription(app); return app; }; diff --git a/back/api/subscription.ts b/back/api/subscription.ts new file mode 100644 index 00000000..4a5dc00a --- /dev/null +++ b/back/api/subscription.ts @@ -0,0 +1,278 @@ +import { Router, Request, Response, NextFunction } from 'express'; +import { Container } from 'typedi'; +import { Logger } from 'winston'; +import SubscriptionService from '../services/subscription'; +import { celebrate, Joi } from 'celebrate'; +import cron_parser from 'cron-parser'; +const route = Router(); + +export default (app: Router) => { + app.use('/subscriptions', route); + + route.get('/', async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.list( + req.query.searchValue as string, + ); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }); + + route.post( + '/', + celebrate({ + body: Joi.object({ + type: Joi.string().required(), + schedule: Joi.string().required(), + name: Joi.string().optional(), + url: Joi.string().required(), + whitelist: Joi.string().optional(), + blacklist: Joi.string().optional(), + branch: Joi.string().optional(), + dependences: Joi.string().optional(), + status: Joi.number().optional(), + pull_type: Joi.string().optional(), + pull_option: Joi.object().optional(), + schedule_type: Joi.number().optional(), + alias: Joi.number().required(), + }), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + if (cron_parser.parseExpression(req.body.schedule).hasNext()) { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.create(req.body); + return res.send({ code: 200, data }); + } else { + return res.send({ code: 400, message: 'param schedule error' }); + } + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.put( + '/run', + celebrate({ + body: Joi.array().items(Joi.number().required()), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.run(req.body); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.put( + '/stop', + celebrate({ + body: Joi.array().items(Joi.number().required()), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.stop(req.body); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.put( + '/disable', + celebrate({ + body: Joi.array().items(Joi.number().required()), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.disabled(req.body); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.put( + '/enable', + celebrate({ + body: Joi.array().items(Joi.number().required()), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.enabled(req.body); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.get( + '/:id/log', + celebrate({ + params: Joi.object({ + id: Joi.number().required(), + }), + }), + async (req: Request<{ id: number }>, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.log(req.params.id); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.put( + '/', + celebrate({ + body: Joi.object({ + type: Joi.string().required(), + schedule: Joi.string().required(), + name: Joi.string().optional(), + url: Joi.string().required(), + whitelist: Joi.string().optional(), + blacklist: Joi.string().optional(), + branch: Joi.string().optional(), + dependences: Joi.string().optional(), + status: Joi.number().optional(), + pull_type: Joi.string().optional(), + pull_option: Joi.object().optional(), + schedule_type: Joi.number().optional(), + alias: Joi.number().required(), + id: Joi.number().required(), + }), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + if ( + !req.body.schedule || + cron_parser.parseExpression(req.body.schedule).hasNext() + ) { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.update(req.body); + return res.send({ code: 200, data }); + } else { + return res.send({ code: 400, message: 'param schedule error' }); + } + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.delete( + '/', + celebrate({ + body: Joi.array().items(Joi.number().required()), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.remove(req.body); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.get( + '/:id', + celebrate({ + params: Joi.object({ + id: Joi.number().required(), + }), + }), + async (req: Request<{ id: number }>, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.getDb({ id: req.params.id }); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.put( + '/status', + celebrate({ + body: Joi.object({ + ids: Joi.array().items(Joi.number().required()), + status: Joi.string().required(), + pid: Joi.string().optional(), + log_path: Joi.string().optional(), + }), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.status({ + ...req.body, + status: parseInt(req.body.status), + pid: parseInt(req.body.pid) || '', + }); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.get( + '/:id/logs', + celebrate({ + params: Joi.object({ + id: Joi.number().required(), + }), + }), + async (req: Request<{ id: number }>, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const subscriptionService = Container.get(SubscriptionService); + const data = await subscriptionService.logs(req.params.id); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); +}; diff --git a/back/loaders/db.ts b/back/loaders/db.ts index 10f97cc4..3d52bd56 100644 --- a/back/loaders/db.ts +++ b/back/loaders/db.ts @@ -8,6 +8,7 @@ import { AppModel } from '../data/open'; import { AuthModel } from '../data/auth'; import { sequelize } from '../data'; import { fileExist } from '../config/util'; +import { SubscriptionModel } from '../data/subscription'; import config from '../config'; export default async () => { @@ -17,6 +18,8 @@ export default async () => { await AppModel.sync(); await AuthModel.sync(); await EnvModel.sync(); + await SubscriptionModel.sync(); + await sequelize.sync(); // try { diff --git a/back/services/subscription.ts b/back/services/subscription.ts index c71ec5b1..58062ff8 100644 --- a/back/services/subscription.ts +++ b/back/services/subscription.ts @@ -19,6 +19,62 @@ import path from 'path'; export default class SubscriptionService { constructor(@Inject('logger') private logger: winston.Logger) {} + public async list(searchText?: string): Promise { + let query = {}; + if (searchText) { + const textArray = searchText.split(':'); + switch (textArray[0]) { + case 'name': + case 'command': + case 'schedule': + case 'label': + const column = textArray[0] === 'label' ? 'labels' : textArray[0]; + query = { + [column]: { + [Op.or]: [ + { [Op.like]: `%${textArray[1]}%` }, + { [Op.like]: `%${encodeURIComponent(textArray[1])}%` }, + ], + }, + }; + break; + default: + const reg = { + [Op.or]: [ + { [Op.like]: `%${searchText}%` }, + { [Op.like]: `%${encodeURIComponent(searchText)}%` }, + ], + }; + query = { + [Op.or]: [ + { + name: reg, + }, + { + command: reg, + }, + { + schedule: reg, + }, + { + labels: reg, + }, + ], + }; + break; + } + } + try { + const result = await SubscriptionModel.findAll({ + where: query, + order: [['createdAt', 'DESC']], + }); + return result as any; + } catch (error) { + throw error; + } + } + public async create(payload: Subscription): Promise { const tab = new Subscription(payload); const doc = await this.insert(tab);