修复环境变量位置计算逻辑

This commit is contained in:
whyour 2022-11-02 00:02:15 +08:00
parent f93cbbf508
commit 8f90d3f8ff
12 changed files with 61 additions and 36 deletions

View File

@ -109,7 +109,6 @@ export default (app: Router) => {
}), }),
}), }),
async (req: Request<{ id: number }>, res: Response, next: NextFunction) => { async (req: Request<{ id: number }>, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try { try {
const envService = Container.get(EnvService); const envService = Container.get(EnvService);
const data = await envService.move(req.params.id, req.body); const data = await envService.move(req.params.id, req.body);

View File

@ -26,7 +26,10 @@ export enum EnvStatus {
'disabled', 'disabled',
} }
export const initEnvPosition = 9999999999; export const maxPosition = 9000000000000000;
export const initPosition = 4500000000000000;
export const stepPosition = 10000000;
export const minPosition = 100;
interface EnvInstance extends Model<Env, Env>, Env {} interface EnvInstance extends Model<Env, Env>, Env {}
export const EnvModel = sequelize.define<EnvInstance>('Env', { export const EnvModel = sequelize.define<EnvInstance>('Env', {

View File

@ -4,7 +4,7 @@ import { Container } from 'typedi';
import { Crontab, CrontabModel, CrontabStatus } from '../data/cron'; import { Crontab, CrontabModel, CrontabStatus } from '../data/cron';
import CronService from '../services/cron'; import CronService from '../services/cron';
import EnvService from '../services/env'; import EnvService from '../services/env';
import _ from 'lodash'; import groupBy from 'lodash/groupBy';
import { DependenceModel } from '../data/dependence'; import { DependenceModel } from '../data/dependence';
import { Op } from 'sequelize'; import { Op } from 'sequelize';
import config from '../config'; import config from '../config';
@ -26,7 +26,7 @@ export default async () => {
order: [['type', 'DESC']], order: [['type', 'DESC']],
raw: true, raw: true,
}).then(async (docs) => { }).then(async (docs) => {
const groups = _.groupBy(docs, 'type'); const groups = groupBy(docs, 'type');
const keys = Object.keys(groups).sort((a, b) => parseInt(b) - parseInt(a)); const keys = Object.keys(groups).sort((a, b) => parseInt(b) - parseInt(a));
for (const key of keys) { for (const key of keys) {
const group = groups[key]; const group = groups[key];

View File

@ -1,5 +1,4 @@
import { Container } from 'typedi'; import { Container } from 'typedi';
import _ from 'lodash';
import SystemService from '../services/system'; import SystemService from '../services/system';
import ScheduleService from '../services/schedule'; import ScheduleService from '../services/schedule';
import SubscriptionService from '../services/subscription'; import SubscriptionService from '../services/subscription';

View File

@ -1,14 +1,14 @@
import { Service, Inject } from 'typedi'; import { Service, Inject } from 'typedi';
import winston from 'winston'; import winston from 'winston';
import { CrontabView, CrontabViewModel } from '../data/cronView'; import { CrontabView, CrontabViewModel } from '../data/cronView';
import { initEnvPosition } from '../data/env'; import { initPosition } from '../data/env';
@Service() @Service()
export default class CronViewService { export default class CronViewService {
constructor(@Inject('logger') private logger: winston.Logger) {} constructor(@Inject('logger') private logger: winston.Logger) {}
public async create(payload: CrontabView): Promise<CrontabView> { public async create(payload: CrontabView): Promise<CrontabView> {
let position = initEnvPosition; let position = initPosition;
const views = await this.list(); const views = await this.list();
if (views && views.length > 0 && views[views.length - 1].position) { if (views && views.length > 0 && views[views.length - 1].position) {
position = views[views.length - 1].position as number; position = views[views.length - 1].position as number;

View File

@ -9,7 +9,6 @@ import {
unInstallDependenceCommandTypes, unInstallDependenceCommandTypes,
DependenceModel, DependenceModel,
} from '../data/dependence'; } from '../data/dependence';
import _ from 'lodash';
import { spawn } from 'child_process'; import { spawn } from 'child_process';
import SockService from './sock'; import SockService from './sock';
import { Op } from 'sequelize'; import { Op } from 'sequelize';

View File

@ -1,10 +1,17 @@
import { Service, Inject } from 'typedi'; import { Service, Inject } from 'typedi';
import winston from 'winston'; import winston from 'winston';
import { getFileContentByName } from '../config/util';
import config from '../config'; import config from '../config';
import * as fs from 'fs'; import * as fs from 'fs';
import { Env, EnvModel, EnvStatus, initEnvPosition } from '../data/env'; import {
import _ from 'lodash'; Env,
EnvModel,
EnvStatus,
initPosition,
maxPosition,
minPosition,
stepPosition,
} from '../data/env';
import groupBy from 'lodash/groupBy';
import { Op } from 'sequelize'; import { Op } from 'sequelize';
@Service() @Service()
@ -13,17 +20,22 @@ export default class EnvService {
public async create(payloads: Env[]): Promise<Env[]> { public async create(payloads: Env[]): Promise<Env[]> {
const envs = await this.envs(); const envs = await this.envs();
let position = initEnvPosition; let position = initPosition;
if (envs && envs.length > 0 && envs[envs.length - 1].position) { if (
position = envs[envs.length - 1].position as number; envs &&
envs.length > 0 &&
typeof envs[envs.length - 1].position === 'number'
) {
position = envs[envs.length - 1].position!;
} }
const tabs = payloads.map((x) => { const tabs = payloads.map((x) => {
position = position / 2; position = position - stepPosition;
const tab = new Env({ ...x, position }); const tab = new Env({ ...x, position });
return tab; return tab;
}); });
const docs = await this.insert(tabs); const docs = await this.insert(tabs);
await this.set_envs(); await this.set_envs();
await this.checkPosition(tabs[tabs.length - 1].position!);
return docs; return docs;
} }
@ -67,25 +79,40 @@ export default class EnvService {
const envs = await this.envs(); const envs = await this.envs();
if (toIndex === 0 || toIndex === envs.length - 1) { if (toIndex === 0 || toIndex === envs.length - 1) {
targetPosition = isUpward targetPosition = isUpward
? envs[0].position! * 2 ? envs[0].position! + stepPosition
: envs[toIndex].position! / 2; : envs[toIndex].position! - stepPosition;
} else { } else {
targetPosition = isUpward targetPosition = isUpward
? (envs[toIndex].position! + envs[toIndex - 1].position!) / 2 ? (envs[toIndex].position! + envs[toIndex - 1].position!) / 2
: (envs[toIndex].position! + envs[toIndex + 1].position!) / 2; : (envs[toIndex].position! + envs[toIndex + 1].position!) / 2;
} }
const newDoc = await this.update({ const newDoc = await this.update({
id, id,
position: targetPosition, position: this.getPrecisionPosition(targetPosition),
}); });
await this.checkPosition(targetPosition);
return newDoc; return newDoc;
} }
public async envs( private async checkPosition(position: number) {
searchText: string = '', const precisionPosition = parseFloat(position.toPrecision(16));
sort: any = { position: -1 }, if (precisionPosition < minPosition || precisionPosition > maxPosition) {
query: any = {}, const envs = await this.envs();
): Promise<Env[]> { let position = initPosition;
for (const env of envs) {
position = position - stepPosition;
await this.updateDb({ ...env, position });
}
}
}
private getPrecisionPosition(position: number): number {
return parseFloat(position.toPrecision(16));
}
public async envs(searchText: string = '', query: any = {}): Promise<Env[]> {
let condition = { ...query }; let condition = { ...query };
if (searchText) { if (searchText) {
const encodeText = encodeURIComponent(searchText); const encodeText = encodeURIComponent(searchText);
@ -155,12 +182,11 @@ export default class EnvService {
} }
public async set_envs() { public async set_envs() {
const envs = await this.envs( const envs = await this.envs('', {
'', name: { [Op.not]: null },
{ position: -1 }, status: EnvStatus.normal,
{ name: { [Op.not]: null }, status: EnvStatus.normal }, });
); const groups = groupBy(envs, 'name');
const groups = _.groupBy(envs, 'name');
let env_string = ''; let env_string = '';
for (const key in groups) { for (const key in groups) {
if (Object.prototype.hasOwnProperty.call(groups, key)) { if (Object.prototype.hasOwnProperty.call(groups, key)) {
@ -168,8 +194,8 @@ export default class EnvService {
// 忽略不符合bash要求的环境变量名称 // 忽略不符合bash要求的环境变量名称
if (/^[a-zA-Z_][0-9a-zA-Z_]*$/.test(key)) { if (/^[a-zA-Z_][0-9a-zA-Z_]*$/.test(key)) {
let value = _(group) let value = group
.map('value') .map((x) => x.value)
.join('&') .join('&')
.replace(/(\\)[^n]/g, '\\\\') .replace(/(\\)[^n]/g, '\\\\')
.replace(/(\\$)/, '\\\\') .replace(/(\\$)/, '\\\\')

View File

@ -2,7 +2,6 @@ import { Service, Inject } from 'typedi';
import winston from 'winston'; import winston from 'winston';
import config from '../config'; import config from '../config';
import * as fs from 'fs'; import * as fs from 'fs';
import _ from 'lodash';
import { AuthDataType, AuthInfo, AuthModel, LoginStatus } from '../data/auth'; import { AuthDataType, AuthInfo, AuthModel, LoginStatus } from '../data/auth';
import { NotificationInfo } from '../data/notify'; import { NotificationInfo } from '../data/notify';
import NotificationService from './notify'; import NotificationService from './notify';

View File

@ -3,7 +3,6 @@ import winston from 'winston';
import { createRandomString, getNetIp, getPlatform } from '../config/util'; import { createRandomString, getNetIp, getPlatform } from '../config/util';
import config from '../config'; import config from '../config';
import * as fs from 'fs'; import * as fs from 'fs';
import _ from 'lodash';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import { authenticator } from '@otplib/preset-default'; import { authenticator } from '@otplib/preset-default';
import { AuthDataType, AuthInfo, AuthModel, LoginStatus } from '../data/auth'; import { AuthDataType, AuthInfo, AuthModel, LoginStatus } from '../data/auth';

View File

@ -97,7 +97,7 @@
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/express-jwt": "^6.0.4", "@types/express-jwt": "^6.0.4",
"@types/jsonwebtoken": "^8.5.8", "@types/jsonwebtoken": "^8.5.8",
"@types/lodash": "^4.14.179", "@types/lodash": "^4.14.185",
"@types/multer": "^1.4.7", "@types/multer": "^1.4.7",
"@types/nedb": "^1.8.12", "@types/nedb": "^1.8.12",
"@types/node": "^17.0.21", "@types/node": "^17.0.21",

View File

@ -21,7 +21,8 @@ import { useOutletContext } from '@umijs/max';
import { SharedContext } from '@/layouts'; import { SharedContext } from '@/layouts';
import { DeleteOutlined } from '@ant-design/icons'; import { DeleteOutlined } from '@ant-design/icons';
import { depthFirstSearch } from '@/utils'; import { depthFirstSearch } from '@/utils';
import { debounce, uniq } from 'lodash'; import debounce from 'lodash/groupBy';
import uniq from 'lodash/uniq';
import useFilterTreeData from '@/hooks/useFilterTreeData'; import useFilterTreeData from '@/hooks/useFilterTreeData';
const { Text } = Typography; const { Text } = Typography;

View File

@ -38,7 +38,7 @@ import { parse } from 'query-string';
import { depthFirstSearch } from '@/utils'; import { depthFirstSearch } from '@/utils';
import { SharedContext } from '@/layouts'; import { SharedContext } from '@/layouts';
import useFilterTreeData from '@/hooks/useFilterTreeData'; import useFilterTreeData from '@/hooks/useFilterTreeData';
import { uniq } from 'lodash'; import uniq from 'lodash/uniq';
const { Text } = Typography; const { Text } = Typography;