mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-22 22:36:06 +08:00
系统设置增加依赖代理和镜像设置
This commit is contained in:
parent
9b7d4cb8fe
commit
3777a4e7b4
|
@ -6,7 +6,6 @@ import config from '../config';
|
|||
import SystemService from '../services/system';
|
||||
import { celebrate, Joi } from 'celebrate';
|
||||
import UserService from '../services/user';
|
||||
import { EnvModel } from '../data/env';
|
||||
import {
|
||||
getUniqPath,
|
||||
handleLogPath,
|
||||
|
@ -78,18 +77,16 @@ export default (app: Router) => {
|
|||
);
|
||||
|
||||
route.put(
|
||||
'/config',
|
||||
'/config/log-remove-frequency',
|
||||
celebrate({
|
||||
body: Joi.object({
|
||||
logRemoveFrequency: Joi.number().optional().allow(null),
|
||||
cronConcurrency: Joi.number().optional().allow(null),
|
||||
logRemoveFrequency: Joi.number().allow(null),
|
||||
}),
|
||||
}),
|
||||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const systemService = Container.get(SystemService);
|
||||
const result = await systemService.updateSystemConfig(req.body);
|
||||
const result = await systemService.updateLogRemoveFrequency(req.body);
|
||||
res.send(result);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
|
@ -97,6 +94,96 @@ export default (app: Router) => {
|
|||
},
|
||||
);
|
||||
|
||||
route.put(
|
||||
'/config/cron-concurrency',
|
||||
celebrate({
|
||||
body: Joi.object({
|
||||
cronConcurrency: Joi.number().allow(null),
|
||||
}),
|
||||
}),
|
||||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const systemService = Container.get(SystemService);
|
||||
const result = await systemService.updateCronConcurrency(req.body);
|
||||
res.send(result);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
route.put(
|
||||
'/config/dependence-proxy',
|
||||
celebrate({
|
||||
body: Joi.object({
|
||||
dependenceProxy: Joi.string().allow('').allow(null),
|
||||
}),
|
||||
}),
|
||||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const systemService = Container.get(SystemService);
|
||||
const result = await systemService.updateDependenceProxy(req.body);
|
||||
res.send(result);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
route.put(
|
||||
'/config/node-mirror',
|
||||
celebrate({
|
||||
body: Joi.object({
|
||||
nodeMirror: Joi.string().allow('').allow(null),
|
||||
}),
|
||||
}),
|
||||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const systemService = Container.get(SystemService);
|
||||
res.setHeader('Content-type', 'application/octet-stream');
|
||||
await systemService.updateNodeMirror(req.body, res);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
route.put(
|
||||
'/config/python-mirror',
|
||||
celebrate({
|
||||
body: Joi.object({
|
||||
pythonMirror: Joi.string().allow('').allow(null),
|
||||
}),
|
||||
}),
|
||||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const systemService = Container.get(SystemService);
|
||||
const result = await systemService.updatePythonMirror(req.body);
|
||||
res.send(result);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
route.put(
|
||||
'/config/linux-mirror',
|
||||
celebrate({
|
||||
body: Joi.object({
|
||||
linuxMirror: Joi.string().allow('').allow(null),
|
||||
}),
|
||||
}),
|
||||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const systemService = Container.get(SystemService);
|
||||
res.setHeader('Content-type', 'application/octet-stream');
|
||||
await systemService.updateLinuxMirror(req.body, res);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
route.put(
|
||||
'/update-check',
|
||||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
|
|
|
@ -47,6 +47,7 @@ const configString = 'config sample crontab shareCode diy';
|
|||
const versionFile = path.join(rootPath, 'version.yaml');
|
||||
const dataTgzFile = path.join(tmpPath, 'data.tgz');
|
||||
const shareShellFile = path.join(shellPath, 'share.sh');
|
||||
const dependenceProxyFile = path.join(configPath, 'dependence-proxy.sh');
|
||||
|
||||
if (envFound.error) {
|
||||
throw new Error("⚠️ Couldn't find .env file ⚠️");
|
||||
|
@ -68,6 +69,7 @@ export default {
|
|||
dataPath,
|
||||
dataTgzFile,
|
||||
shareShellFile,
|
||||
dependenceProxyFile,
|
||||
configString,
|
||||
loginFaild,
|
||||
authError,
|
||||
|
@ -89,6 +91,7 @@ export default {
|
|||
'config.sh.sample',
|
||||
'cookie.sh',
|
||||
'crontab.list',
|
||||
'dependence-proxy.sh',
|
||||
'env.sh',
|
||||
'token.json',
|
||||
],
|
||||
|
|
|
@ -496,4 +496,4 @@ export async function rmPath(path: string) {
|
|||
} catch (error) {
|
||||
Logger.error('[rmPath失败]', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
import { spawn } from 'cross-spawn';
|
||||
import SockService from './sock';
|
||||
import { FindOptions, Op } from 'sequelize';
|
||||
import { promiseExecSuccess } from '../config/util';
|
||||
import { fileExist, promiseExecSuccess } from '../config/util';
|
||||
import dayjs from 'dayjs';
|
||||
import taskLimit from '../shared/pLimit';
|
||||
|
||||
|
@ -252,10 +252,18 @@ export default class DependenceService {
|
|||
return resolve(null);
|
||||
}
|
||||
}
|
||||
|
||||
const cp = spawn(`${depRunCommand} ${dependency.name.trim()}`, {
|
||||
shell: '/bin/bash',
|
||||
});
|
||||
const dependenceProxyFileExist = await fileExist(
|
||||
config.dependenceProxyFile,
|
||||
);
|
||||
const proxyStr = dependenceProxyFileExist
|
||||
? `pnpm config get registry && source ${config.dependenceProxyFile} &&`
|
||||
: '';
|
||||
const cp = spawn(
|
||||
`${proxyStr} ${depRunCommand} ${dependency.name.trim()}`,
|
||||
{
|
||||
shell: '/bin/bash',
|
||||
},
|
||||
);
|
||||
|
||||
cp.stdout.on('data', async (data) => {
|
||||
this.sockService.sendMessage({
|
||||
|
|
|
@ -75,31 +75,140 @@ export default class SystemService {
|
|||
}
|
||||
}
|
||||
|
||||
public async updateSystemConfig(info: SystemModelInfo) {
|
||||
public async updateLogRemoveFrequency(info: SystemModelInfo) {
|
||||
const oDoc = await this.getSystemConfig();
|
||||
const result = await this.updateAuthDb({
|
||||
...oDoc,
|
||||
info,
|
||||
info: { ...oDoc.info, ...info },
|
||||
});
|
||||
if (info.logRemoveFrequency) {
|
||||
const cron = {
|
||||
id: result.id || NaN,
|
||||
name: '删除日志',
|
||||
command: `ql rmlog ${info.logRemoveFrequency}`,
|
||||
};
|
||||
const cron = {
|
||||
id: result.id || NaN,
|
||||
name: '删除日志',
|
||||
command: `ql rmlog ${info.logRemoveFrequency}`,
|
||||
};
|
||||
if (oDoc.info?.logRemoveFrequency) {
|
||||
await this.scheduleService.cancelIntervalTask(cron);
|
||||
if (info.logRemoveFrequency > 0) {
|
||||
this.scheduleService.createIntervalTask(cron, {
|
||||
days: info.logRemoveFrequency,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (info.logRemoveFrequency && info.logRemoveFrequency > 0) {
|
||||
this.scheduleService.createIntervalTask(cron, {
|
||||
days: info.logRemoveFrequency,
|
||||
});
|
||||
}
|
||||
return { code: 200, data: info };
|
||||
}
|
||||
|
||||
public async updateCronConcurrency(info: SystemModelInfo) {
|
||||
const oDoc = await this.getSystemConfig();
|
||||
await this.updateAuthDb({
|
||||
...oDoc,
|
||||
info: { ...oDoc.info, ...info },
|
||||
});
|
||||
if (info.cronConcurrency) {
|
||||
await taskLimit.setCustomLimit(info.cronConcurrency);
|
||||
}
|
||||
return { code: 200, data: info };
|
||||
}
|
||||
|
||||
public async updateDependenceProxy(info: SystemModelInfo) {
|
||||
const oDoc = await this.getSystemConfig();
|
||||
await this.updateAuthDb({
|
||||
...oDoc,
|
||||
info: { ...oDoc.info, ...info },
|
||||
});
|
||||
if (info.dependenceProxy) {
|
||||
await fs.promises.writeFile(
|
||||
config.dependenceProxyFile,
|
||||
`export http_proxy="${info.dependenceProxy}"\nexport https_proxy="${info.dependenceProxy}"`,
|
||||
);
|
||||
} else {
|
||||
await fs.promises.rm(config.dependenceProxyFile);
|
||||
}
|
||||
return { code: 200, data: info };
|
||||
}
|
||||
|
||||
public async updateNodeMirror(info: SystemModelInfo, res: Response) {
|
||||
const oDoc = await this.getSystemConfig();
|
||||
await this.updateAuthDb({
|
||||
...oDoc,
|
||||
info: { ...oDoc.info, ...info },
|
||||
});
|
||||
let cmd = 'pnpm config delete registry';
|
||||
if (info.nodeMirror) {
|
||||
cmd = `pnpm config set registry ${info.nodeMirror}`;
|
||||
}
|
||||
const command = `cd && ${cmd} && pnpm i -g`;
|
||||
this.scheduleService.runTask(
|
||||
command,
|
||||
{
|
||||
onStart: async (cp) => {
|
||||
res.setHeader('QL-Task-Pid', `${cp.pid}`);
|
||||
},
|
||||
onEnd: async () => {
|
||||
res.end();
|
||||
},
|
||||
onError: async (message: string) => {
|
||||
res.write(`\n${message}`);
|
||||
},
|
||||
onLog: async (message: string) => {
|
||||
res.write(`\n${message}`);
|
||||
},
|
||||
},
|
||||
{
|
||||
command,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public async updatePythonMirror(info: SystemModelInfo) {
|
||||
const oDoc = await this.getSystemConfig();
|
||||
await this.updateAuthDb({
|
||||
...oDoc,
|
||||
info: { ...oDoc.info, ...info },
|
||||
});
|
||||
let cmd = 'pip config unset global.index-url';
|
||||
if (info.pythonMirror) {
|
||||
cmd = `pip3 config set global.index-url ${info.pythonMirror}`;
|
||||
}
|
||||
await promiseExec(cmd);
|
||||
return { code: 200, data: info };
|
||||
}
|
||||
|
||||
public async updateLinuxMirror(info: SystemModelInfo, res: Response) {
|
||||
const oDoc = await this.getSystemConfig();
|
||||
await this.updateAuthDb({
|
||||
...oDoc,
|
||||
info: { ...oDoc.info, ...info },
|
||||
});
|
||||
let targetDomain = 'dl-cdn.alpinelinux.org';
|
||||
if (info.linuxMirror) {
|
||||
targetDomain = info.linuxMirror;
|
||||
}
|
||||
const command = `sed -i 's/${
|
||||
oDoc.info?.linuxMirror || 'dl-cdn.alpinelinux.org'
|
||||
}/${targetDomain}/g' /etc/apk/repositories && apk update -f`;
|
||||
|
||||
this.scheduleService.runTask(
|
||||
command,
|
||||
{
|
||||
onStart: async (cp) => {
|
||||
res.setHeader('QL-Task-Pid', `${cp.pid}`);
|
||||
},
|
||||
onEnd: async () => {
|
||||
res.end();
|
||||
},
|
||||
onError: async (message: string) => {
|
||||
res.write(`\n${message}`);
|
||||
},
|
||||
onLog: async (message: string) => {
|
||||
res.write(`\n${message}`);
|
||||
},
|
||||
},
|
||||
{
|
||||
command,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public async checkUpdate() {
|
||||
try {
|
||||
const currentVersionContent = await parseVersion(config.versionFile);
|
||||
|
|
|
@ -86,7 +86,6 @@
|
|||
"p-queue-cjs": "7.3.4",
|
||||
"protobufjs": "^7.2.3",
|
||||
"pstree.remy": "^1.1.8",
|
||||
"react-hotkeys-hook": "^4.4.1",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"sequelize": "^6.25.5",
|
||||
"serve-handler": "^6.1.3",
|
||||
|
@ -140,10 +139,11 @@
|
|||
"axios": "^1.4.0",
|
||||
"compression-webpack-plugin": "9.2.0",
|
||||
"concurrently": "^7.0.0",
|
||||
"react-hotkeys-hook": "^4.4.1",
|
||||
"file-saver": "^2.0.5",
|
||||
"lint-staged": "^13.0.3",
|
||||
"monaco-editor": "0.33.0",
|
||||
"nodemon": "^2.0.15",
|
||||
"nodemon": "^3.0.1",
|
||||
"prettier": "^2.5.1",
|
||||
"qiniu": "^7.4.0",
|
||||
"qrcode.react": "^1.0.1",
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@grpc/grpc-js':
|
||||
specifier: ^1.8.13
|
||||
|
@ -98,9 +94,6 @@ dependencies:
|
|||
pstree.remy:
|
||||
specifier: ^1.1.8
|
||||
version: 1.1.8
|
||||
react-hotkeys-hook:
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1(react-dom@18.2.0)(react@18.2.0)
|
||||
reflect-metadata:
|
||||
specifier: ^0.1.13
|
||||
version: 0.1.13
|
||||
|
@ -266,8 +259,8 @@ devDependencies:
|
|||
specifier: 0.33.0
|
||||
version: 0.33.0
|
||||
nodemon:
|
||||
specifier: ^2.0.15
|
||||
version: 2.0.22
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.1
|
||||
prettier:
|
||||
specifier: ^2.5.1
|
||||
version: 2.8.8
|
||||
|
@ -304,6 +297,9 @@ devDependencies:
|
|||
react-dom:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0(react@18.2.0)
|
||||
react-hotkeys-hook:
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1(react-dom@18.2.0)(react@18.2.0)
|
||||
react-intl-universal:
|
||||
specifier: ^2.6.21
|
||||
version: 2.6.21(react@18.2.0)
|
||||
|
@ -4139,7 +4135,7 @@ packages:
|
|||
requiresBuild: true
|
||||
dependencies:
|
||||
'@gar/promisify': 1.1.3
|
||||
semver: 7.5.1
|
||||
semver: 7.5.4
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
|
@ -5182,7 +5178,7 @@ packages:
|
|||
ignore: 5.2.4
|
||||
natural-compare-lite: 1.4.0
|
||||
regexpp: 3.2.0
|
||||
semver: 7.5.1
|
||||
semver: 7.5.4
|
||||
tsutils: 3.21.0(typescript@5.2.2)
|
||||
typescript: 5.2.2
|
||||
transitivePeerDependencies:
|
||||
|
@ -5273,7 +5269,7 @@ packages:
|
|||
debug: 4.3.4
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.5.1
|
||||
semver: 7.5.4
|
||||
tsutils: 3.21.0(typescript@5.2.2)
|
||||
typescript: 5.2.2
|
||||
transitivePeerDependencies:
|
||||
|
@ -5294,7 +5290,7 @@ packages:
|
|||
debug: 4.3.4
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.5.1
|
||||
semver: 7.5.4
|
||||
tsutils: 3.21.0(typescript@5.2.2)
|
||||
typescript: 5.2.2
|
||||
transitivePeerDependencies:
|
||||
|
@ -5318,7 +5314,7 @@ packages:
|
|||
eslint: 8.35.0
|
||||
eslint-scope: 5.1.1
|
||||
eslint-utils: 3.0.0(eslint@8.35.0)
|
||||
semver: 7.5.1
|
||||
semver: 7.5.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
@ -5341,7 +5337,7 @@ packages:
|
|||
'@typescript-eslint/typescript-estree': 5.59.9(typescript@5.2.2)
|
||||
eslint: 8.35.0
|
||||
eslint-scope: 5.1.1
|
||||
semver: 7.5.1
|
||||
semver: 7.5.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
@ -7717,7 +7713,7 @@ packages:
|
|||
postcss-modules-scope: 3.0.0(postcss@8.4.24)
|
||||
postcss-modules-values: 4.0.0(postcss@8.4.24)
|
||||
postcss-value-parser: 4.2.0
|
||||
semver: 7.5.1
|
||||
semver: 7.5.4
|
||||
webpack: 5.85.1
|
||||
dev: true
|
||||
|
||||
|
@ -9053,7 +9049,7 @@ packages:
|
|||
minimatch: 3.1.2
|
||||
node-abort-controller: 3.1.1
|
||||
schema-utils: 3.1.2
|
||||
semver: 7.5.1
|
||||
semver: 7.5.4
|
||||
tapable: 2.2.1
|
||||
typescript: 5.2.2
|
||||
webpack: 5.85.1
|
||||
|
@ -10291,6 +10287,7 @@ packages:
|
|||
|
||||
/js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
dev: true
|
||||
|
||||
/js-yaml@3.14.1:
|
||||
resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
|
||||
|
@ -10745,6 +10742,7 @@ packages:
|
|||
hasBin: true
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
dev: true
|
||||
|
||||
/lower-case@2.0.2:
|
||||
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
||||
|
@ -11323,9 +11321,9 @@ packages:
|
|||
engines: {node: '>=6.0.0'}
|
||||
dev: false
|
||||
|
||||
/nodemon@2.0.22:
|
||||
resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
/nodemon@3.0.1:
|
||||
resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
chokidar: 3.5.3
|
||||
|
@ -11333,8 +11331,8 @@ packages:
|
|||
ignore-by-default: 1.0.1
|
||||
minimatch: 3.1.2
|
||||
pstree.remy: 1.1.8
|
||||
semver: 5.7.1
|
||||
simple-update-notifier: 1.1.0
|
||||
semver: 7.5.4
|
||||
simple-update-notifier: 2.0.0
|
||||
supports-color: 5.5.0
|
||||
touch: 3.1.0
|
||||
undefsafe: 2.0.5
|
||||
|
@ -11370,7 +11368,7 @@ packages:
|
|||
dependencies:
|
||||
hosted-git-info: 4.1.0
|
||||
is-core-module: 2.12.1
|
||||
semver: 7.5.1
|
||||
semver: 7.5.4
|
||||
validate-npm-package-license: 3.0.4
|
||||
dev: true
|
||||
|
||||
|
@ -13705,6 +13703,7 @@ packages:
|
|||
loose-envify: 1.4.0
|
||||
react: 18.2.0
|
||||
scheduler: 0.23.0
|
||||
dev: true
|
||||
|
||||
/react-easy-crop@4.7.4(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-oDi1375Jo/zuPUvo3oauxnNbfy8L4wsbmHD1KB2vT55fdgu+q8/K0w/rDWzy9jz4jfQ94Q9+3Yu366sDDFVmiA==}
|
||||
|
@ -13784,7 +13783,7 @@ packages:
|
|||
dependencies:
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/react-intl-universal@2.6.21(react@18.2.0):
|
||||
resolution: {integrity: sha512-JJqZMzdB6jd4f0NfGRc9XM/pZElxtrDCWC9pE2yIesDO70SL+jQgaFAucQmstPwYqCcjvLpCgOrjP7cIo4kJnw==}
|
||||
|
@ -14002,6 +14001,7 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
dev: true
|
||||
|
||||
/reactcss@1.2.3(react@18.2.0):
|
||||
resolution: {integrity: sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==}
|
||||
|
@ -14362,6 +14362,7 @@ packages:
|
|||
resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
dev: true
|
||||
|
||||
/schema-utils@3.1.2:
|
||||
resolution: {integrity: sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==}
|
||||
|
@ -14405,17 +14406,20 @@ packages:
|
|||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
|
||||
/semver@7.0.0:
|
||||
resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/semver@7.5.1:
|
||||
resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
dev: false
|
||||
|
||||
/semver@7.5.4:
|
||||
resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
|
||||
/send@0.18.0:
|
||||
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
|
||||
|
@ -14597,11 +14601,11 @@ packages:
|
|||
is-arrayish: 0.3.2
|
||||
dev: false
|
||||
|
||||
/simple-update-notifier@1.1.0:
|
||||
resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
/simple-update-notifier@2.0.0:
|
||||
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
semver: 7.0.0
|
||||
semver: 7.5.4
|
||||
dev: true
|
||||
|
||||
/single-spa@5.9.4:
|
||||
|
@ -16388,3 +16392,7 @@ packages:
|
|||
- encoding
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
|
|
@ -472,7 +472,7 @@
|
|||
"Python 软件包镜像源": "Python Software Package Mirror Source",
|
||||
"Linux 软件包镜像源": "Linux Software Package Mirror Source",
|
||||
"代理与镜像源二选一即可": "Either Proxy or Mirror Source can be chosen",
|
||||
"代理地址, 支持HTTP(S)/SOCK5": "Proxy Address, supports HTTP(S)/SOCK5",
|
||||
"代理地址, 支持HTTP(S)/SOCK5, ip:port": "Proxy Address, supports HTTP(S)/SOCK5, ip:port",
|
||||
"NPM 镜像源": "NPM Mirror Source",
|
||||
"PyPI 镜像源": "PyPI Mirror Source",
|
||||
"alpine linux 镜像源": "Alpine Linux Mirror Source"
|
||||
|
|
|
@ -472,7 +472,7 @@
|
|||
"Python 软件包镜像源": "Python 软件包镜像源",
|
||||
"Linux 软件包镜像源": "Linux 软件包镜像源",
|
||||
"代理与镜像源二选一即可": "代理与镜像源二选一即可",
|
||||
"代理地址, 支持HTTP(S)/SOCK5": "代理地址, 支持HTTP(S)/SOCK5",
|
||||
"代理地址, 支持HTTP(S)/SOCK5, ip:port": "代理地址, 支持HTTP(S)/SOCK5, ip:port",
|
||||
"NPM 镜像源": "NPM 镜像源",
|
||||
"PyPI 镜像源": "PyPI 镜像源",
|
||||
"alpine linux 镜像源": "alpine linux 镜像源"
|
||||
|
|
|
@ -15,6 +15,7 @@ import CodeMirror from '@uiw/react-codemirror';
|
|||
import { useOutletContext } from '@umijs/max';
|
||||
import { SharedContext } from '@/layouts';
|
||||
import { langs } from '@uiw/codemirror-extensions-langs';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
|
||||
const Config = () => {
|
||||
const { headerStyle, isPhone, theme } = useOutletContext<SharedContext>();
|
||||
|
@ -68,6 +69,14 @@ const Config = () => {
|
|||
getConfig(node.value);
|
||||
};
|
||||
|
||||
useHotkeys(
|
||||
'meta+s',
|
||||
(e) => {
|
||||
updateConfig();
|
||||
},
|
||||
{ enableOnFormTags: ['textarea'], preventDefault: true },
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
getFiles();
|
||||
getConfig('config.sh');
|
||||
|
|
|
@ -4,6 +4,15 @@ import { Button, InputNumber, Form, message, Input, Alert } from 'antd';
|
|||
import config from '@/utils/config';
|
||||
import { request } from '@/utils/http';
|
||||
import './index.less';
|
||||
import Ansi from 'ansi-to-react';
|
||||
import pick from 'lodash/pick';
|
||||
|
||||
const dataMap = {
|
||||
'dependence-proxy': 'dependenceProxy',
|
||||
'node-mirror': 'nodeMirror',
|
||||
'python-mirror': 'pythonMirror',
|
||||
'linux-mirror': 'linuxMirror',
|
||||
};
|
||||
|
||||
const Dependence = () => {
|
||||
const [systemConfig, setSystemConfig] = useState<{
|
||||
|
@ -13,6 +22,7 @@ const Dependence = () => {
|
|||
linuxMirror?: string;
|
||||
}>();
|
||||
const [form] = Form.useForm();
|
||||
const [log, setLog] = useState<string>('');
|
||||
|
||||
const getSystemConfig = () => {
|
||||
request
|
||||
|
@ -27,9 +37,31 @@ const Dependence = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const updateSystemConfig = () => {
|
||||
const updateSystemConfigStream = (path: keyof typeof dataMap) => {
|
||||
setLog('执行中...');
|
||||
request
|
||||
.put(`${config.apiPrefix}system/config`, systemConfig)
|
||||
.put<string>(
|
||||
`${config.apiPrefix}system/config/${path}`,
|
||||
pick(systemConfig, dataMap[path]),
|
||||
{
|
||||
responseType: 'stream',
|
||||
},
|
||||
)
|
||||
.then((res) => {
|
||||
setLog(() => res);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
const updateSystemConfig = (path: keyof typeof dataMap) => {
|
||||
setLog('');
|
||||
request
|
||||
.put(
|
||||
`${config.apiPrefix}system/config/${path}`,
|
||||
pick(systemConfig, dataMap[path]),
|
||||
)
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success(intl.get('更新成功'));
|
||||
|
@ -45,94 +77,120 @@ const Dependence = () => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<Form layout="vertical" form={form}>
|
||||
<Form.Item
|
||||
label={intl.get('代理')}
|
||||
name="proxy"
|
||||
extra={intl.get('代理与镜像源二选一即可')}
|
||||
<div className="dependence-config-wrapper">
|
||||
<Form layout="vertical" form={form}>
|
||||
<Form.Item
|
||||
label={intl.get('代理')}
|
||||
name="proxy"
|
||||
extra={intl.get('代理与镜像源二选一即可')}
|
||||
>
|
||||
<Input.Group compact>
|
||||
<Input
|
||||
placeholder={intl.get('代理地址, 支持HTTP(S)/SOCK5, ip:port')}
|
||||
style={{ width: 330 }}
|
||||
value={systemConfig?.dependenceProxy}
|
||||
onChange={(e) => {
|
||||
setSystemConfig({
|
||||
...systemConfig,
|
||||
dependenceProxy: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
updateSystemConfig('dependence-proxy');
|
||||
}}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
</Button>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label={intl.get('Node 软件包镜像源')} name="node">
|
||||
<Input.Group compact>
|
||||
<Input
|
||||
style={{ width: 330 }}
|
||||
placeholder={intl.get('NPM 镜像源')}
|
||||
value={systemConfig?.nodeMirror}
|
||||
onChange={(e) => {
|
||||
setSystemConfig({
|
||||
...systemConfig,
|
||||
nodeMirror: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
updateSystemConfigStream('node-mirror');
|
||||
}}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
</Button>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label={intl.get('Python 软件包镜像源')} name="python">
|
||||
<Input.Group compact>
|
||||
<Input
|
||||
style={{ width: 330 }}
|
||||
placeholder={intl.get('PyPI 镜像源')}
|
||||
value={systemConfig?.pythonMirror}
|
||||
onChange={(e) => {
|
||||
setSystemConfig({
|
||||
...systemConfig,
|
||||
pythonMirror: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
updateSystemConfig('python-mirror');
|
||||
}}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
</Button>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label={intl.get('Linux 软件包镜像源')} name="linux">
|
||||
<Input.Group compact>
|
||||
<Input
|
||||
style={{ width: 330 }}
|
||||
placeholder={intl.get('alpine linux 镜像源')}
|
||||
value={systemConfig?.linuxMirror}
|
||||
onChange={(e) => {
|
||||
setSystemConfig({
|
||||
...systemConfig,
|
||||
linuxMirror: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
updateSystemConfigStream('linux-mirror');
|
||||
}}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
</Button>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<pre
|
||||
style={{
|
||||
fontFamily: 'Source Code Pro',
|
||||
zoom: 0.83,
|
||||
maxHeight: '100%',
|
||||
overflowY: 'auto'
|
||||
}}
|
||||
>
|
||||
<Input.Group compact>
|
||||
<Input
|
||||
placeholder={intl.get('代理地址, 支持HTTP(S)/SOCK5')}
|
||||
style={{ width: 330 }}
|
||||
value={systemConfig?.dependenceProxy}
|
||||
onChange={(e) => {
|
||||
setSystemConfig({
|
||||
...systemConfig,
|
||||
dependenceProxy: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={updateSystemConfig}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
</Button>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label={intl.get('Node 软件包镜像源')} name="node">
|
||||
<Input.Group compact>
|
||||
<Input
|
||||
style={{ width: 330 }}
|
||||
placeholder={intl.get('NPM 镜像源')}
|
||||
value={systemConfig?.nodeMirror}
|
||||
onChange={(e) => {
|
||||
setSystemConfig({ ...systemConfig, nodeMirror: e.target.value });
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={updateSystemConfig}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
</Button>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label={intl.get('Python 软件包镜像源')} name="python">
|
||||
<Input.Group compact>
|
||||
<Input
|
||||
style={{ width: 330 }}
|
||||
placeholder={intl.get('PyPI 镜像源')}
|
||||
value={systemConfig?.pythonMirror}
|
||||
onChange={(e) => {
|
||||
setSystemConfig({
|
||||
...systemConfig,
|
||||
pythonMirror: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={updateSystemConfig}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
</Button>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label={intl.get('Linux 软件包镜像源')} name="linux">
|
||||
<Input.Group compact>
|
||||
<Input
|
||||
style={{ width: 330 }}
|
||||
placeholder={intl.get('alpine linux 镜像源')}
|
||||
value={systemConfig?.linuxMirror}
|
||||
onChange={(e) => {
|
||||
setSystemConfig({ ...systemConfig, linuxMirror: e.target.value });
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={updateSystemConfig}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
</Button>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<Ansi>{log}</Ansi>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -27,3 +27,8 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dependence-config-wrapper {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,12 @@ import './index.less';
|
|||
import { UploadOutlined } from '@ant-design/icons';
|
||||
import Countdown from 'antd/lib/statistic/Countdown';
|
||||
import useProgress from './progress';
|
||||
import pick from 'lodash/pick';
|
||||
|
||||
const dataMap = {
|
||||
'log-remove-frequency': 'logRemoveFrequency',
|
||||
'cron-concurrency': 'cronConcurrency',
|
||||
};
|
||||
|
||||
const Other = ({
|
||||
systemInfo,
|
||||
|
@ -32,7 +38,6 @@ const Other = ({
|
|||
cronConcurrency?: number | null;
|
||||
}>();
|
||||
const [form] = Form.useForm();
|
||||
const modalRef = useRef<any>();
|
||||
const [exportLoading, setExportLoading] = useState(false);
|
||||
const showUploadProgress = useProgress(intl.get('上传'));
|
||||
const showDownloadProgress = useProgress(intl.get('下载'));
|
||||
|
@ -80,9 +85,12 @@ const Other = ({
|
|||
});
|
||||
};
|
||||
|
||||
const updateSystemConfig = () => {
|
||||
const updateSystemConfig = (path: keyof typeof dataMap) => {
|
||||
request
|
||||
.put(`${config.apiPrefix}system/config`, systemConfig)
|
||||
.put(
|
||||
`${config.apiPrefix}system/config/${path}`,
|
||||
pick(systemConfig, dataMap[path]),
|
||||
)
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success(intl.get('更新成功'));
|
||||
|
@ -207,7 +215,9 @@ const Other = ({
|
|||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={updateSystemConfig}
|
||||
onClick={() => {
|
||||
updateSystemConfig('log-remove-frequency');
|
||||
}}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
|
@ -226,7 +236,9 @@ const Other = ({
|
|||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={updateSystemConfig}
|
||||
onClick={() => {
|
||||
updateSystemConfig('cron-concurrency');
|
||||
}}
|
||||
style={{ width: 84 }}
|
||||
>
|
||||
{intl.get('确认')}
|
||||
|
|
Loading…
Reference in New Issue
Block a user