From 7038e15ad284baf9d074fe75ab3d64543bc0aa37 Mon Sep 17 00:00:00 2001 From: whyour Date: Thu, 10 Nov 2022 01:31:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E8=A7=86=E5=9B=BE=E7=AD=9B=E9=80=89=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/cron.ts | 2 + back/data/cronView.ts | 6 +- back/data/subscription.ts | 3 + back/loaders/db.ts | 4 +- back/services/cron.ts | 7 +- back/services/cronView.ts | 29 ++++++++- back/services/system.ts | 9 ++- package.json | 2 +- src/components/iconfont.tsx | 2 +- src/pages/crontab/index.less | 2 +- src/pages/crontab/index.tsx | 32 +++++---- src/pages/crontab/viewCreateModal.tsx | 93 ++++++++++++++++----------- 12 files changed, 127 insertions(+), 64 deletions(-) diff --git a/back/api/cron.ts b/back/api/cron.ts index b2435464..027e0f84 100644 --- a/back/api/cron.ts +++ b/back/api/cron.ts @@ -30,6 +30,7 @@ export default (app: Router) => { name: Joi.string().required(), sorts: Joi.array().optional().allow(null), filters: Joi.array().optional(), + filterRelation: Joi.string().optional(), }), }), async (req: Request, res: Response, next: NextFunction) => { @@ -51,6 +52,7 @@ export default (app: Router) => { id: Joi.number().required(), sorts: Joi.array().optional().allow(null), filters: Joi.array().optional(), + filterRelation: Joi.string().optional(), }), }), async (req: Request, res: Response, next: NextFunction) => { diff --git a/back/data/cronView.ts b/back/data/cronView.ts index 36bd3d9c..3dfd055d 100644 --- a/back/data/cronView.ts +++ b/back/data/cronView.ts @@ -7,7 +7,8 @@ interface SortType { } interface FilterType { - type: 'or' | 'and'; + property: string; + operation: string; value: string; } @@ -18,6 +19,7 @@ export class CrontabView { isDisabled?: 1 | 0; filters?: FilterType[]; sorts?: SortType[]; + filterRelation?: 'and' | 'or'; constructor(options: CrontabView) { this.name = options.name; @@ -26,6 +28,7 @@ export class CrontabView { this.isDisabled = options.isDisabled || 0; this.filters = options.filters; this.sorts = options.sorts; + this.filterRelation = options.filterRelation; } } @@ -43,5 +46,6 @@ export const CrontabViewModel = sequelize.define( isDisabled: DataTypes.NUMBER, filters: DataTypes.JSON, sorts: DataTypes.JSON, + filterRelation: { type: DataTypes.STRING, defaultValue: 'and' }, }, ); diff --git a/back/data/subscription.ts b/back/data/subscription.ts index a3877033..e319a36a 100644 --- a/back/data/subscription.ts +++ b/back/data/subscription.ts @@ -28,6 +28,7 @@ export class Subscription { extensions?: string; sub_before?: string; sub_after?: string; + proxy?: string; constructor(options: Subscription) { this.id = options.id; @@ -54,6 +55,7 @@ export class Subscription { this.extensions = options.extensions; this.sub_before = options.sub_before; this.sub_after = options.sub_after; + this.proxy = options.proxy; } } @@ -102,5 +104,6 @@ export const SubscriptionModel = sequelize.define( log_path: DataTypes.STRING, schedule_type: DataTypes.STRING, alias: { type: DataTypes.STRING, unique: 'alias' }, + proxy: { type: DataTypes.STRING, allowNull: true }, }, ); diff --git a/back/loaders/db.ts b/back/loaders/db.ts index 6a4308ee..ced837c2 100644 --- a/back/loaders/db.ts +++ b/back/loaders/db.ts @@ -18,8 +18,8 @@ export default async () => { await AppModel.sync(); await AuthModel.sync(); await EnvModel.sync(); - await SubscriptionModel.sync(); - await CrontabViewModel.sync(); + await SubscriptionModel.sync({ alter: true }); + await CrontabViewModel.sync({ alter: true }); // try { // const queryInterface = sequelize.getQueryInterface(); diff --git a/back/services/cron.ts b/back/services/cron.ts index bbf6fa2e..1a1e34fa 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -116,8 +116,9 @@ export default class CronService { private formatViewQuery(query: any, viewQuery: any) { if (viewQuery.filters && viewQuery.filters.length > 0) { - if (!query[Op.and]) { - query[Op.and] = []; + const primaryOperate = viewQuery.filterRelation === 'or' ? Op.or : Op.and; + if (!query[primaryOperate]) { + query[primaryOperate] = []; } for (const col of viewQuery.filters) { const { property, value, operation } = col; @@ -166,7 +167,7 @@ export default class CronService { ], }; } - query[Op.and].push(q); + query[primaryOperate].push(q); } } } diff --git a/back/services/cronView.ts b/back/services/cronView.ts index 766aa780..4c079112 100644 --- a/back/services/cronView.ts +++ b/back/services/cronView.ts @@ -1,7 +1,12 @@ import { Service, Inject } from 'typedi'; import winston from 'winston'; import { CrontabView, CrontabViewModel } from '../data/cronView'; -import { initPosition } from '../data/env'; +import { + initPosition, + maxPosition, + minPosition, + stepPosition, +} from '../data/env'; @Service() export default class CronViewService { @@ -16,6 +21,8 @@ export default class CronViewService { position = position / 2; const tab = new CrontabView({ ...payload, position }); const doc = await this.insert(tab); + + await this.checkPosition(tab.position!); return doc; } @@ -62,6 +69,22 @@ export default class CronViewService { await CrontabViewModel.update({ isDisabled: 0 }, { where: { id: ids } }); } + private async checkPosition(position: number) { + const precisionPosition = parseFloat(position.toPrecision(16)); + if (precisionPosition < minPosition || precisionPosition > maxPosition) { + const envs = await this.list(); + let position = initPosition; + for (const env of envs) { + position = position - stepPosition; + await this.updateDb({ id: env.id, position }); + } + } + } + + private getPrecisionPosition(position: number): number { + return parseFloat(position.toPrecision(16)); + } + public async move({ id, fromIndex, @@ -85,8 +108,10 @@ export default class CronViewService { } const newDoc = await this.update({ id, - position: targetPosition, + position: this.getPrecisionPosition(targetPosition), }); + + await this.checkPosition(targetPosition); return newDoc; } } diff --git a/back/services/system.ts b/back/services/system.ts index 749fd91f..ec272e5a 100644 --- a/back/services/system.ts +++ b/back/services/system.ts @@ -9,7 +9,6 @@ import ScheduleService from './schedule'; import { spawn } from 'child_process'; import SockService from './sock'; import got from 'got'; -import { promiseExec } from '../config/util'; @Service() export default class SystemService { @@ -88,9 +87,13 @@ export default class SystemService { let lastVersion = ''; let lastLog = ''; try { - const lastVersionFileContent = await promiseExec( - `curl ${config.lastVersionFile}?t=${Date.now()}`, + const result = await got.get( + `${config.lastVersionFile}?t=${Date.now()}`, + { + timeout: 30000, + }, ); + const lastVersionFileContent = result.body; lastVersion = lastVersionFileContent.match(versionRegx)![1]; lastLog = lastVersionFileContent.match(logRegx) ? lastVersionFileContent.match(logRegx)![1] diff --git a/package.json b/package.json index 57b2c2b4..e4413b4f 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "nodemailer": "^6.7.2", "p-queue": "7.2.0", "reflect-metadata": "^0.1.13", - "sequelize": "^6.25.3", + "sequelize": "^6.25.5", "serve-handler": "^6.1.3", "sockjs": "^0.3.24", "sqlite3": "npm:@louislam/sqlite3@^15.0.6", diff --git a/src/components/iconfont.tsx b/src/components/iconfont.tsx index ede96ae4..1bab8044 100644 --- a/src/components/iconfont.tsx +++ b/src/components/iconfont.tsx @@ -1,7 +1,7 @@ import { createFromIconfontCN } from '@ant-design/icons'; const IconFont = createFromIconfontCN({ - scriptUrl: ['//at.alicdn.com/t/font_3354854_ds8pa06q1qa.js'], + scriptUrl: ['//at.alicdn.com/t/c/font_3354854_z0d9rbri1ci.js'], }); export default IconFont; diff --git a/src/pages/crontab/index.less b/src/pages/crontab/index.less index 37d84d8b..b31ac988 100644 --- a/src/pages/crontab/index.less +++ b/src/pages/crontab/index.less @@ -179,6 +179,6 @@ tr.drop-over-upward td { .view-filters-container.active { .filter-item > div > .ant-form-item-control { - padding-left: 40px; + margin-left: 40px; } } diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 2e873e00..c50c7f50 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -201,10 +201,10 @@ const Crontab = () => { > {record.last_execution_time ? new Date(record.last_execution_time * 1000) - .toLocaleString(language, { - hour12: false, - }) - .replace(' 24:', ' 00:') + .toLocaleString(language, { + hour12: false, + }) + .replace(' 24:', ' 00:') : '-'} ); @@ -387,7 +387,7 @@ const Crontab = () => { const [enabledCronViews, setEnabledCronViews] = useState([]); const [moreMenuActive, setMoreMenuActive] = useState(false); const tableRef = useRef(); - const tableScrollHeight = useTableScrollHeight(tableRef) + const tableScrollHeight = useTableScrollHeight(tableRef); const goToScriptManager = (record: any) => { const cmd = record.command.split(' ') as string[]; @@ -414,10 +414,11 @@ const Crontab = () => { const getCrons = () => { setLoading(true); const { page, size, sorter, filters } = pageConf; - let url = `${config.apiPrefix - }crons?searchValue=${searchText}&page=${page}&size=${size}&filters=${JSON.stringify( - filters, - )}`; + let url = `${ + config.apiPrefix + }crons?searchValue=${searchText}&page=${page}&size=${size}&filters=${JSON.stringify( + filters, + )}`; if (sorter && sorter.field) { url += `&sorter=${JSON.stringify({ field: sorter.field, @@ -428,6 +429,7 @@ const Crontab = () => { url += `&queryString=${JSON.stringify({ filters: viewConf.filters, sorts: viewConf.sorts, + filterRelation: viewConf.filterRelation || 'and', })}`; } request @@ -582,7 +584,8 @@ const Crontab = () => { onOk() { request .put( - `${config.apiPrefix}crons/${record.isDisabled === 1 ? 'enable' : 'disable' + `${config.apiPrefix}crons/${ + record.isDisabled === 1 ? 'enable' : 'disable' }`, { data: [record.id], @@ -625,7 +628,8 @@ const Crontab = () => { onOk() { request .put( - `${config.apiPrefix}crons/${record.isPinned === 1 ? 'unpin' : 'pin' + `${config.apiPrefix}crons/${ + record.isPinned === 1 ? 'unpin' : 'pin' }`, { data: [record.id], @@ -999,7 +1003,11 @@ const Crontab = () => {
{selectedRowIds.length > 0 && (
- -
- ) - } + <> + {ViewFilterRelation[filterRelation]} + + + +
+ )}