@whyour/qinglong 2.18.3-3 → 2.19.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/.env.example +7 -9
  2. package/docker/310.Dockerfile +18 -9
  3. package/docker/Dockerfile +18 -9
  4. package/docker/docker-entrypoint.sh +14 -15
  5. package/docker/front.conf +0 -32
  6. package/ecosystem.config.js +5 -25
  7. package/package.json +9 -11
  8. package/sample/notify.js +5 -3
  9. package/shell/check.sh +0 -2
  10. package/shell/preload/sitecustomize.js +38 -15
  11. package/shell/preload/sitecustomize.py +42 -18
  12. package/shell/share.sh +23 -75
  13. package/shell/update.sh +21 -20
  14. package/static/build/api/health.js +32 -0
  15. package/static/build/api/index.js +4 -0
  16. package/static/build/api/log.js +1 -1
  17. package/static/build/api/script.js +2 -3
  18. package/static/build/api/system.js +1 -0
  19. package/static/build/api/update.js +47 -0
  20. package/static/build/api/user.js +2 -2
  21. package/static/build/app.js +70 -21
  22. package/static/build/config/const.js +2 -1
  23. package/static/build/config/index.js +32 -25
  24. package/static/build/config/util.js +72 -89
  25. package/static/build/data/dependence.js +1 -13
  26. package/static/build/data/notify.js +1 -0
  27. package/static/build/loaders/app.js +7 -9
  28. package/static/build/loaders/db.js +1 -3
  29. package/static/build/loaders/express.js +1 -9
  30. package/static/build/loaders/initData.js +7 -8
  31. package/static/build/loaders/initFile.js +0 -1
  32. package/static/build/loaders/logger.js +34 -15
  33. package/static/build/middlewares/monitoring.js +56 -0
  34. package/static/build/schedule/api.js +47 -8
  35. package/static/build/schedule/client.js +1 -1
  36. package/static/build/services/cron.js +12 -6
  37. package/static/build/services/dependence.js +10 -9
  38. package/static/build/services/grpc.js +97 -0
  39. package/static/build/services/health.js +74 -0
  40. package/static/build/services/http.js +68 -0
  41. package/static/build/services/metrics.js +82 -0
  42. package/static/build/services/notify.js +3 -3
  43. package/static/build/services/system.js +8 -1
  44. package/static/build/services/user.js +21 -5
  45. package/static/build/shared/pLimit.js +13 -1
  46. package/static/dist/{2208.03c2cf4a.async.js → 2208.98ccac5f.async.js} +1 -1
  47. package/static/dist/8826.faecf076.async.js +1 -0
  48. package/static/dist/8851.cf7e0ebc.async.js +1 -0
  49. package/static/dist/index.html +2 -2
  50. package/static/dist/layouts__index.6e23431c.async.js +1 -0
  51. package/static/dist/{preload_helper.1b1a7a9f.js → preload_helper.67e88ed6.js} +1 -1
  52. package/static/dist/{src__pages__crontab__index.5eb33581.async.js → src__pages__crontab__index.d6d37f6a.async.js} +1 -1
  53. package/static/dist/{src__pages__crontab__modal.b20074c2.async.js → src__pages__crontab__modal.dcd053b5.async.js} +1 -1
  54. package/static/dist/src__pages__dependence__modal.7f588c0b.async.js +1 -0
  55. package/static/dist/src__pages__env__editNameModal.411043e2.async.js +1 -0
  56. package/static/dist/{src__pages__env__modal.d923acdb.async.js → src__pages__env__modal.7d952f26.async.js} +1 -1
  57. package/static/dist/src__pages__error__index.837f4753.async.js +1 -0
  58. package/static/dist/{src__pages__initialization__index.684197ee.async.js → src__pages__initialization__index.5bd471c5.async.js} +1 -1
  59. package/static/dist/src__pages__script__editNameModal.32bb2f80.async.js +1 -0
  60. package/static/dist/src__pages__script__index.53f99bee.async.js +1 -0
  61. package/static/dist/{src__pages__script__renameModal.09dfb133.async.js → src__pages__script__renameModal.8232c924.async.js} +1 -1
  62. package/static/dist/{src__pages__script__saveModal.21b81bcc.async.js → src__pages__script__saveModal.8e358e84.async.js} +1 -1
  63. package/static/dist/{src__pages__script__setting.c6503aaf.async.js → src__pages__script__setting.dcdd7253.async.js} +1 -1
  64. package/static/dist/{src__pages__setting__appModal.b115baf8.async.js → src__pages__setting__appModal.25adf30e.async.js} +1 -1
  65. package/static/dist/src__pages__setting__dependence.95dd01e7.async.js +1 -0
  66. package/static/dist/src__pages__setting__index.3b426f9f.async.js +1 -0
  67. package/static/dist/src__pages__setting__notification.989e57d6.async.js +1 -0
  68. package/static/dist/src__pages__setting__security.7623a492.async.js +1 -0
  69. package/static/dist/src__pages__setting__systemLog.2e8cc7a0.async.js +1 -0
  70. package/static/dist/src__pages__subscription__modal.46a69195.async.js +1 -0
  71. package/static/dist/{umi.32588872.js → umi.b7656bb3.js} +1 -1
  72. package/version.yaml +12 -6
  73. package/back.d.ts +0 -9
  74. package/other.config.js +0 -13
  75. package/static/build/loaders/update.js +0 -79
  76. package/static/build/public.js +0 -34
  77. package/static/build/schedule/index.js +0 -52
  78. package/static/build/update.js +0 -29
  79. package/static/dist/8826.b3f9fa78.async.js +0 -1
  80. package/static/dist/8851.a57942be.async.js +0 -1
  81. package/static/dist/layouts__index.623b87d2.async.js +0 -1
  82. package/static/dist/src__pages__dependence__modal.1bb8572d.async.js +0 -1
  83. package/static/dist/src__pages__env__editNameModal.115bb8ea.async.js +0 -1
  84. package/static/dist/src__pages__error__index.a17578c5.async.js +0 -1
  85. package/static/dist/src__pages__script__editNameModal.7d1cc6b4.async.js +0 -1
  86. package/static/dist/src__pages__script__index.0cd08dcd.async.js +0 -1
  87. package/static/dist/src__pages__setting__dependence.f3afc194.async.js +0 -1
  88. package/static/dist/src__pages__setting__index.34ed674c.async.js +0 -1
  89. package/static/dist/src__pages__setting__notification.b7722a0b.async.js +0 -1
  90. package/static/dist/src__pages__setting__security.534a5e67.async.js +0 -1
  91. package/static/dist/src__pages__setting__systemLog.cb8a2174.async.js +0 -1
  92. package/static/dist/src__pages__subscription__modal.10cd630d.async.js +0 -1
@@ -109,6 +109,7 @@ let DependenceService = class DependenceService {
109
109
  docs.forEach((dep) => {
110
110
  this.installOrUninstallDependency(dep, isInstall, force);
111
111
  });
112
+ return pLimit_1.default.waitDependencyQueueDone();
112
113
  }
113
114
  async reInstall(ids) {
114
115
  await dependence_1.DependenceModel.update({ status: dependence_1.DependenceStatus.queued, log: [] }, { where: { id: ids } });
@@ -120,8 +121,8 @@ let DependenceService = class DependenceService {
120
121
  const docs = await dependence_1.DependenceModel.findAll({ where: { id: ids } });
121
122
  for (const doc of docs) {
122
123
  pLimit_1.default.removeQueuedDependency(doc);
123
- let depInstallCommand = dependence_1.InstallDependenceCommandTypes[doc.type];
124
- let depUnInstallCommand = dependence_1.unInstallDependenceCommandTypes[doc.type];
124
+ let depInstallCommand = (0, util_1.getInstallCommand)(doc.type, doc.name);
125
+ let depUnInstallCommand = (0, util_1.getUninstallCommand)(doc.type, doc.name);
125
126
  const isLinuxDependence = doc.type === dependence_1.DependenceTypes.linux;
126
127
  if (isLinuxDependence) {
127
128
  const osType = await (0, util_2.detectOS)();
@@ -206,13 +207,13 @@ let DependenceService = class DependenceService {
206
207
  ? dependence_1.DependenceStatus.installing
207
208
  : dependence_1.DependenceStatus.removing;
208
209
  await dependence_1.DependenceModel.update({ status }, { where: { id: depIds } });
209
- let depRunCommand = (isInstall
210
- ? dependence_1.InstallDependenceCommandTypes
211
- : dependence_1.unInstallDependenceCommandTypes)[dependency.type];
210
+ let command = isInstall
211
+ ? (0, util_1.getInstallCommand)(dependency.type, depName)
212
+ : (0, util_1.getUninstallCommand)(dependency.type, depName);
212
213
  if (isLinuxDependence) {
213
- depRunCommand = isInstall
214
- ? linuxCommand.install
215
- : linuxCommand.uninstall;
214
+ command = isInstall
215
+ ? `${linuxCommand.install} ${depName.trim()}`
216
+ : `${linuxCommand.uninstall} ${depName.trim()}`;
216
217
  }
217
218
  const startTime = (0, dayjs_1.default)();
218
219
  const message = `开始${actionText}依赖 ${depName},开始时间 ${startTime.format('YYYY-MM-DD HH:mm:ss')}\n\n`;
@@ -265,7 +266,7 @@ let DependenceService = class DependenceService {
265
266
  const proxyStr = dependenceProxyFileExist
266
267
  ? `source ${config_1.default.dependenceProxyFile} &&`
267
268
  : '';
268
- const cp = (0, cross_spawn_1.spawn)(`${proxyStr} ${depRunCommand} ${dependency.name.trim()}`, {
269
+ const cp = (0, cross_spawn_1.spawn)(`${proxyStr} ${command}`, {
269
270
  shell: '/bin/bash',
270
271
  });
271
272
  cp.stdout.on('data', async (data) => {
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
31
+ var __importDefault = (this && this.__importDefault) || function (mod) {
32
+ return (mod && mod.__esModule) ? mod : { "default": mod };
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.GrpcServerService = void 0;
36
+ const grpc_js_1 = require("@grpc/grpc-js");
37
+ const cron_1 = require("../protos/cron");
38
+ const health_1 = require("../protos/health");
39
+ const api_1 = require("../protos/api");
40
+ const addCron_1 = require("../schedule/addCron");
41
+ const delCron_1 = require("../schedule/delCron");
42
+ const health_2 = require("../schedule/health");
43
+ const Api = __importStar(require("../schedule/api"));
44
+ const logger_1 = __importDefault(require("../loaders/logger"));
45
+ const util_1 = require("util");
46
+ const config_1 = __importDefault(require("../config"));
47
+ const metrics_1 = require("./metrics");
48
+ const typedi_1 = require("typedi");
49
+ let GrpcServerService = class GrpcServerService {
50
+ constructor() {
51
+ this.server = new grpc_js_1.Server({ 'grpc.enable_http_proxy': 0 });
52
+ }
53
+ async initialize() {
54
+ try {
55
+ this.server.addService(health_1.HealthService, { check: health_2.check });
56
+ this.server.addService(cron_1.CronService, { addCron: addCron_1.addCron, delCron: delCron_1.delCron });
57
+ this.server.addService(api_1.ApiService, Api);
58
+ const grpcPort = config_1.default.grpcPort;
59
+ const bindAsync = (0, util_1.promisify)(this.server.bindAsync).bind(this.server);
60
+ await bindAsync(`0.0.0.0:${grpcPort}`, grpc_js_1.ServerCredentials.createInsecure());
61
+ logger_1.default.debug(`✌️ gRPC service started successfully`);
62
+ metrics_1.metricsService.record('grpc_service_start', 1, {
63
+ port: grpcPort.toString(),
64
+ });
65
+ return grpcPort;
66
+ }
67
+ catch (err) {
68
+ logger_1.default.error('Failed to start gRPC service:', err);
69
+ throw err;
70
+ }
71
+ }
72
+ async shutdown() {
73
+ try {
74
+ if (this.server) {
75
+ await new Promise((resolve) => {
76
+ this.server.tryShutdown(() => {
77
+ logger_1.default.debug('gRPC service stopped');
78
+ metrics_1.metricsService.record('grpc_service_stop', 1);
79
+ resolve(null);
80
+ });
81
+ });
82
+ }
83
+ }
84
+ catch (err) {
85
+ logger_1.default.error('Error while shutting down gRPC service:', err);
86
+ throw err;
87
+ }
88
+ }
89
+ getServer() {
90
+ return this.server;
91
+ }
92
+ };
93
+ exports.GrpcServerService = GrpcServerService;
94
+ exports.GrpcServerService = GrpcServerService = __decorate([
95
+ (0, typedi_1.Service)()
96
+ ], GrpcServerService);
97
+ //# sourceMappingURL=grpc.js.map
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.HealthService = void 0;
16
+ const typedi_1 = require("typedi");
17
+ const logger_1 = __importDefault(require("../loaders/logger"));
18
+ const grpc_1 = require("./grpc");
19
+ const http_1 = require("./http");
20
+ let HealthService = class HealthService {
21
+ constructor(grpcServerService, httpServerService) {
22
+ this.grpcServerService = grpcServerService;
23
+ this.httpServerService = httpServerService;
24
+ this.startTime = Date.now();
25
+ }
26
+ async check() {
27
+ const status = {
28
+ status: 'ok',
29
+ services: {
30
+ http: true,
31
+ grpc: true,
32
+ },
33
+ metrics: {
34
+ uptime: Math.floor((Date.now() - this.startTime) / 1000),
35
+ memory: {
36
+ used: process.memoryUsage().heapUsed,
37
+ total: process.memoryUsage().heapTotal,
38
+ },
39
+ },
40
+ };
41
+ try {
42
+ const httpServer = this.httpServerService.getServer();
43
+ if (!httpServer) {
44
+ status.services.http = false;
45
+ status.status = 'error';
46
+ }
47
+ }
48
+ catch (err) {
49
+ status.services.http = false;
50
+ status.status = 'error';
51
+ logger_1.default.error('HTTP server check failed:', err);
52
+ }
53
+ try {
54
+ const grpcServer = this.grpcServerService.getServer();
55
+ if (!grpcServer) {
56
+ status.services.grpc = false;
57
+ status.status = 'error';
58
+ }
59
+ }
60
+ catch (err) {
61
+ status.services.grpc = false;
62
+ status.status = 'error';
63
+ logger_1.default.error('gRPC server check failed:', err);
64
+ }
65
+ return status;
66
+ }
67
+ };
68
+ exports.HealthService = HealthService;
69
+ exports.HealthService = HealthService = __decorate([
70
+ (0, typedi_1.Service)(),
71
+ __metadata("design:paramtypes", [grpc_1.GrpcServerService,
72
+ http_1.HttpServerService])
73
+ ], HealthService);
74
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.HttpServerService = void 0;
13
+ const logger_1 = __importDefault(require("../loaders/logger"));
14
+ const metrics_1 = require("./metrics");
15
+ const typedi_1 = require("typedi");
16
+ let HttpServerService = class HttpServerService {
17
+ constructor() {
18
+ this.server = undefined;
19
+ }
20
+ async initialize(expressApp, port) {
21
+ try {
22
+ return new Promise((resolve, reject) => {
23
+ var _a;
24
+ this.server = expressApp.listen(port, '0.0.0.0', () => {
25
+ logger_1.default.debug(`✌️ HTTP service started successfully`);
26
+ metrics_1.metricsService.record('http_service_start', 1, {
27
+ port: port.toString(),
28
+ });
29
+ resolve(this.server);
30
+ });
31
+ (_a = this.server) === null || _a === void 0 ? void 0 : _a.on('error', (err) => {
32
+ logger_1.default.error('Failed to start HTTP service:', err);
33
+ reject(err);
34
+ });
35
+ });
36
+ }
37
+ catch (err) {
38
+ logger_1.default.error('Failed to start HTTP service:', err);
39
+ throw err;
40
+ }
41
+ }
42
+ async shutdown() {
43
+ try {
44
+ if (this.server) {
45
+ await new Promise((resolve) => {
46
+ var _a;
47
+ (_a = this.server) === null || _a === void 0 ? void 0 : _a.close(() => {
48
+ logger_1.default.debug('HTTP service stopped');
49
+ metrics_1.metricsService.record('http_service_stop', 1);
50
+ resolve(null);
51
+ });
52
+ });
53
+ }
54
+ }
55
+ catch (err) {
56
+ logger_1.default.error('Error while shutting down HTTP service:', err);
57
+ throw err;
58
+ }
59
+ }
60
+ getServer() {
61
+ return this.server;
62
+ }
63
+ };
64
+ exports.HttpServerService = HttpServerService;
65
+ exports.HttpServerService = HttpServerService = __decorate([
66
+ (0, typedi_1.Service)()
67
+ ], HttpServerService);
68
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.metricsService = void 0;
7
+ const perf_hooks_1 = require("perf_hooks");
8
+ const logger_1 = __importDefault(require("../loaders/logger"));
9
+ class MetricsService {
10
+ constructor() {
11
+ this.metrics = [];
12
+ // 定期清理旧数据
13
+ setInterval(() => {
14
+ const oneHourAgo = Date.now() - 3600000;
15
+ this.metrics = this.metrics.filter(m => m.timestamp > oneHourAgo);
16
+ }, 60000);
17
+ }
18
+ static getInstance() {
19
+ if (!MetricsService.instance) {
20
+ MetricsService.instance = new MetricsService();
21
+ }
22
+ return MetricsService.instance;
23
+ }
24
+ record(name, value, tags) {
25
+ this.metrics.push({
26
+ name,
27
+ value,
28
+ timestamp: Date.now(),
29
+ tags,
30
+ });
31
+ }
32
+ measure(name, fn, tags) {
33
+ const start = perf_hooks_1.performance.now();
34
+ try {
35
+ fn();
36
+ }
37
+ finally {
38
+ const duration = perf_hooks_1.performance.now() - start;
39
+ this.record(name, duration, tags);
40
+ }
41
+ }
42
+ async measureAsync(name, fn, tags) {
43
+ const start = perf_hooks_1.performance.now();
44
+ try {
45
+ await fn();
46
+ }
47
+ finally {
48
+ const duration = perf_hooks_1.performance.now() - start;
49
+ this.record(name, duration, tags);
50
+ }
51
+ }
52
+ getMetrics(name, tags) {
53
+ let filtered = this.metrics;
54
+ if (name) {
55
+ filtered = filtered.filter(m => m.name === name);
56
+ }
57
+ if (tags) {
58
+ filtered = filtered.filter(m => {
59
+ if (!m.tags)
60
+ return false;
61
+ return Object.entries(tags).every(([key, value]) => m.tags[key] === value);
62
+ });
63
+ }
64
+ return {
65
+ count: filtered.length,
66
+ average: filtered.reduce((acc, curr) => acc + curr.value, 0) / filtered.length,
67
+ min: Math.min(...filtered.map(m => m.value)),
68
+ max: Math.max(...filtered.map(m => m.value)),
69
+ metrics: filtered,
70
+ };
71
+ }
72
+ report() {
73
+ const report = {
74
+ timestamp: Date.now(),
75
+ metrics: this.getMetrics(),
76
+ };
77
+ logger_1.default.info('性能指标报告:', report);
78
+ return report;
79
+ }
80
+ }
81
+ exports.metricsService = MetricsService.getInstance();
82
+ //# sourceMappingURL=metrics.js.map
@@ -73,7 +73,7 @@ let NotificationService = class NotificationService {
73
73
  return await (notificationModeAction === null || notificationModeAction === void 0 ? void 0 : notificationModeAction.call(this));
74
74
  }
75
75
  catch (error) {
76
- throw error;
76
+ console.error(error);
77
77
  }
78
78
  }
79
79
  return false;
@@ -507,7 +507,7 @@ let NotificationService = class NotificationService {
507
507
  }
508
508
  }
509
509
  async email() {
510
- const { emailPass, emailService, emailUser } = this.params;
510
+ const { emailPass, emailService, emailUser, emailTo } = this.params;
511
511
  try {
512
512
  const transporter = nodemailer_1.default.createTransport({
513
513
  service: emailService,
@@ -518,7 +518,7 @@ let NotificationService = class NotificationService {
518
518
  });
519
519
  const info = await transporter.sendMail({
520
520
  from: `"青龙快讯" <${emailUser}>`,
521
- to: `${emailUser}`,
521
+ to: emailTo ? emailTo.split(';') : emailUser,
522
522
  subject: `${this.title}`,
523
523
  html: `${this.content.replace(/\n/g, '<br/>')}`,
524
524
  });
@@ -278,8 +278,15 @@ let SystemService = class SystemService {
278
278
  }
279
279
  async reloadSystem(target) {
280
280
  const cmd = `real_time=true ql reload ${target || ''}`;
281
- const cp = (0, cross_spawn_1.spawn)(cmd, { shell: '/bin/bash' });
281
+ const cp = (0, cross_spawn_1.spawn)(cmd, {
282
+ shell: '/bin/bash',
283
+ detached: true,
284
+ stdio: 'ignore',
285
+ });
282
286
  cp.unref();
287
+ setTimeout(() => {
288
+ process.exit(0);
289
+ });
283
290
  return { code: 200 };
284
291
  }
285
292
  async notify({ title, content }) {
@@ -72,9 +72,9 @@ let UserService = class UserService {
72
72
  }
73
73
  if (username === cUsername && password === cPassword) {
74
74
  const data = (0, util_1.createRandomString)(50, 100);
75
- const expiration = twoFactorActivated ? 60 : 20;
76
- let token = jsonwebtoken_1.default.sign({ data }, config_1.default.secret, {
77
- expiresIn: 60 * 60 * 24 * expiration,
75
+ const expiration = twoFactorActivated ? '60d' : '20d';
76
+ let token = jsonwebtoken_1.default.sign({ data }, config_1.default.jwt.secret, {
77
+ expiresIn: config_1.default.jwt.expiresIn || expiration,
78
78
  algorithm: 'HS384',
79
79
  });
80
80
  await this.updateAuthInfo(content, {
@@ -101,7 +101,14 @@ let UserService = class UserService {
101
101
  this.getLoginLog();
102
102
  return {
103
103
  code: 200,
104
- data: { token, lastip, lastaddr, lastlogon, retries, platform },
104
+ data: {
105
+ token,
106
+ lastip,
107
+ lastaddr,
108
+ lastlogon,
109
+ retries,
110
+ platform,
111
+ },
105
112
  };
106
113
  }
107
114
  else {
@@ -209,7 +216,16 @@ let UserService = class UserService {
209
216
  return this.login({ username, password }, req, false);
210
217
  }
211
218
  else {
212
- const { ip, address } = await (0, util_1.getNetIp)(req);
219
+ const ip = request_ip_1.default.getClientIp(req) || '';
220
+ const query = new ip2region_1.default();
221
+ const ipAddress = query.search(ip);
222
+ let address = '';
223
+ if (ipAddress) {
224
+ const { country, province, city, isp } = ipAddress;
225
+ address = (0, uniq_1.default)([country, province, city, isp])
226
+ .filter(Boolean)
227
+ .join(' ');
228
+ }
213
229
  await this.updateAuthInfo(authInfo, {
214
230
  lastip: ip,
215
231
  lastaddr: address,
@@ -42,7 +42,7 @@ class TaskLimit {
42
42
  this.systemLimit = new p_queue_cjs_1.default({
43
43
  concurrency: Math.max(os_1.default.cpus().length, 4),
44
44
  });
45
- this.client = new api_1.ApiClient(`0.0.0.0:${config_1.default.cronPort}`, grpc_js_1.credentials.createInsecure(), { 'grpc.enable_http_proxy': 0 });
45
+ this.client = new api_1.ApiClient(`0.0.0.0:${config_1.default.grpcPort}`, grpc_js_1.credentials.createInsecure(), { 'grpc.enable_http_proxy': 0 });
46
46
  this.notificationService = new notify_1.default();
47
47
  this.setCustomLimit();
48
48
  this.handleEvents();
@@ -135,6 +135,18 @@ class TaskLimit {
135
135
  fn.schedule = schedule;
136
136
  return this.scriptLimit.add(fn, options);
137
137
  }
138
+ async waitDependencyQueueDone() {
139
+ if (this.dependenyLimit.size === 0 && this.dependenyLimit.pending === 0) {
140
+ return;
141
+ }
142
+ return new Promise((resolve) => {
143
+ const onIdle = () => {
144
+ this.dependenyLimit.removeListener('idle', onIdle);
145
+ resolve();
146
+ };
147
+ this.dependenyLimit.on('idle', onIdle);
148
+ });
149
+ }
138
150
  runDependeny(dependency, fn, options) {
139
151
  this.queuedDependencyIds.add(dependency.id);
140
152
  fn.dependency = dependency;
@@ -1 +1 @@
1
- "use strict";(self.webpackChunk_whyour_qinglong=self.webpackChunk_whyour_qinglong||[]).push([[2208,5812],{44224:function(e,t,r){var a=(0,r(19919).Z)({scriptUrl:["//at.alicdn.com/t/c/font_3354854_lc939gab1iq.js"]});t.Z=a},44860:function(e,t,r){r.r(t),r.d(t,{CrontabStatus:function(){return a},OperationName:function(){return l},OperationPath:function(){return n},ScheduleType:function(){return i}});var a=function(e){return e[e.running=0]="running",e[e.queued=.5]="queued",e[e.idle=1]="idle",e[e.disabled=2]="disabled",e}({}),l=function(e){return e[e["启用"]=0]="启用",e[e["禁用"]=1]="禁用",e[e["运行"]=2]="运行",e[e["停止"]=3]="停止",e[e["置顶"]=4]="置顶",e[e["取消置顶"]=5]="取消置顶",e}({}),n=function(e){return e[e.enable=0]="enable",e[e.disable=1]="disable",e[e.run=2]="run",e[e.stop=3]="stop",e[e.pin=4]="pin",e[e.unpin=5]="unpin",e}({}),i=function(e){return e.Normal="normal",e.Once="once",e.Boot="boot",e}({})},42208:function(e,t,r){r.r(t);var a=r(67825),l=r.n(a),n=r(90228),i=r.n(n),o=r(26068),s=r.n(o),u=r(87999),p=r.n(u),c=r(48305),d=r.n(c),g=r(72317),h=r(75271),m=r(72338),P=r(35181),Z=r(45520),b=r(17082),v=r(93481),f=r(63505),x=r(16314),y=r(3475),k=r(37559),w=r(21288),q=r(44224),j=r(44860),B=r(31352),C=r(52676),_=["name"],S=["key","name"],T=["key","name"],R=[{name:g.ZP.get("命令"),value:"command"},{name:g.ZP.get("名称"),value:"name"},{name:g.ZP.get("定时规则"),value:"schedule"},{name:g.ZP.get("状态"),value:"status",onlySelect:!0},{name:g.ZP.get("标签"),value:"labels"},{name:g.ZP.get("订阅"),value:"sub_id",onlySelect:!0}],I={Reg:"",NotReg:"",In:"select",Nin:"select"},U=[{name:g.ZP.get("包含"),value:"Reg"},{name:g.ZP.get("不包含"),value:"NotReg"},{name:g.ZP.get("属于"),value:"In",type:"select"},{name:g.ZP.get("不属于"),value:"Nin",type:"select"}],K=[{name:g.ZP.get("顺序"),value:"ASC"},{name:g.ZP.get("倒序"),value:"DESC"}],A=function(e){return e.and="且",e.or="或",e}(A||{});t.default=function(e){var t=e.view,r=e.handleCancel,a=e.visible,n=m.Z.useForm(),o=d()(n,1)[0],u=(0,h.useState)(!1),c=d()(u,2),N=c[0],Q=c[1],H=(0,h.useState)("and"),X=d()(H,2),E=X[0],M=X[1],O=m.Z.useWatch("filters",o),W=(0,B.Z)((function(){return x.W.get("".concat(y.Z.apiPrefix,"subscriptions"))}),{cacheKey:"subscriptions"}).data,F={status:[{name:g.ZP.get("运行中"),value:j.CrontabStatus.running},{name:g.ZP.get("空闲中"),value:j.CrontabStatus.idle},{name:g.ZP.get("已禁用"),value:j.CrontabStatus.disabled}],sub_id:null==W?void 0:W.data.map((function(e){return{name:e.name,value:e.id}}))},G=function(){var e=p()(i()().mark((function e(a){var l,n,o,u;return i()().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return Q(!0),a.filterRelation=E,l=t?"put":"post",e.prev=3,e.next=6,x.W[l]("".concat(y.Z.apiPrefix,"crons/views"),t?s()(s()({},a),{},{id:t.id}):a);case 6:n=e.sent,o=n.code,u=n.data,200===o&&r(u),Q(!1),e.next=16;break;case 13:e.prev=13,e.t0=e.catch(3),Q(!1);case 16:case"end":return e.stop()}}),e,null,[[3,13]])})));return function(t){return e.apply(this,arguments)}}();(0,h.useEffect)((function(){t||o.resetFields(),o.setFieldsValue(t||{filters:[{property:"command"}]})}),[t,a]);var D=function(e){var t=e.name,r=l()(e,_),a=o.getFieldValue(["filters",t,"property"]);return(0,C.jsx)(P.Z,s()(s()({style:{width:120},placeholder:g.ZP.get("请选择操作符")},r),{},{children:U.filter((function(e){return F[a]?"select"===e.type:e})).map((function(e){return(0,C.jsx)(P.Z.Option,{value:e.value,children:e.name},e.name)}))}))},L=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return(0,C.jsx)(P.Z,{style:t,children:e.map((function(e){return(0,C.jsx)(P.Z.Option,{value:e.value,children:e.name},e.name)}))})},z=(0,C.jsx)(P.Z,{style:{width:80},children:K.map((function(e){return(0,C.jsx)(P.Z.Option,{value:e.value,children:e.name},e.name)}))});return(0,C.jsx)(Z.Z,{title:t?g.ZP.get("编辑视图"):g.ZP.get("创建视图"),open:a,forceRender:!0,width:580,centered:!0,maskClosable:!1,onOk:function(){o.validateFields().then((function(e){G(e)})).catch((function(e){console.log("Validate Failed:",e)}))},onCancel:function(){return r()},confirmLoading:N,children:(0,C.jsxs)(m.Z,{form:o,layout:"vertical",name:"env_modal",children:[(0,C.jsx)(m.Z.Item,{name:"name",label:g.ZP.get("视图名称"),rules:[{required:!0,message:g.ZP.get("请输入视图名称")}],children:(0,C.jsx)(b.Z,{placeholder:g.ZP.get("请输入视图名称")})}),(0,C.jsx)(m.Z.List,{name:"filters",children:function(e,t,r){var a=t.add,n=t.remove,i=r.errors;return(0,C.jsxs)("div",{style:{position:"relative"},className:"view-filters-container ".concat(e.length>1?"active":""),children:[e.length>1&&(0,C.jsx)("div",{style:{position:"absolute",width:50,borderRadius:10,border:"1px solid rgb(190, 220, 255)",borderRight:"none",height:56*(e.length-1),top:46,left:15},children:(0,C.jsx)(v.Z,{type:"primary",size:"small",style:{position:"absolute",top:"50%",translate:"-50% -50%",padding:"0 3px",cursor:"pointer"},onClick:function(){M("and"===E?"or":"and")},children:(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)("span",{children:A[E]}),(0,C.jsx)(q.Z,{type:"ql-icon-d-caret"})]})})}),(0,C.jsxs)("div",{children:[e.map((function(e){var t,r,a=e.key,i=e.name,o=l()(e,S);return(0,C.jsx)(m.Z.Item,{label:0===i?g.ZP.get("筛选条件"):"",style:{marginBottom:0},required:!0,className:"filter-item",children:(0,C.jsxs)(f.Z,{className:"view-create-modal-filters",align:"baseline",children:[(0,C.jsx)(m.Z.Item,s()(s()({},o),{},{name:[i,"property"],rules:[{required:!0}],children:L(R,{width:120})})),(0,C.jsx)(m.Z.Item,s()(s()({},o),{},{name:[i,"operation"],rules:[{required:!0,message:g.ZP.get("请选择操作符")}],children:(0,C.jsx)(D,{name:i})})),(0,C.jsx)(m.Z.Item,s()(s()({},o),{},{name:[i,"value"],rules:[{required:!0,message:g.ZP.get("请输入内容")}],children:"select"===I[null==O?void 0:O[i].operation]?(t=null==O?void 0:O[i].property,(0,C.jsx)(P.Z,{mode:"tags",allowClear:!0,placeholder:g.ZP.get("输入后回车增加自定义选项"),children:null===(r=F[t])||void 0===r?void 0:r.map((function(e){return(0,C.jsx)(P.Z.Option,{value:e.value,children:e.name},e.name)}))})):(0,C.jsx)(b.Z,{placeholder:g.ZP.get("请输入内容")})})),0!==i&&(0,C.jsx)(k.Z,{onClick:function(){return n(i)}})]})},a)})),(0,C.jsx)(m.Z.Item,{children:(0,C.jsxs)("a",{onClick:function(){return a({property:"command",operation:"Reg"})},children:[(0,C.jsx)(w.Z,{}),g.ZP.get("新增筛选条件")]})}),(0,C.jsx)(m.Z.ErrorList,{errors:i})]})]})}}),(0,C.jsx)(m.Z.List,{name:"sorts",children:function(e,t,r){var a=t.add,n=t.remove,i=r.errors;return(0,C.jsxs)("div",{style:{position:"relative"},className:"view-filters-container ".concat(e.length>1?"active":""),children:[e.length>1&&(0,C.jsx)("div",{style:{position:"absolute",width:50,borderRadius:10,border:"1px solid rgb(190, 220, 255)",borderRight:"none",height:56*(e.length-1),top:46,left:15},children:(0,C.jsx)(v.Z,{type:"primary",size:"small",style:{position:"absolute",top:"50%",translate:"-50% -50%",padding:"0 3px",cursor:"pointer"},children:(0,C.jsx)(C.Fragment,{children:(0,C.jsx)("span",{children:A[E]})})})}),(0,C.jsxs)("div",{children:[e.map((function(e){var t=e.key,r=e.name,a=l()(e,T);return(0,C.jsx)(m.Z.Item,{label:0===r?g.ZP.get("排序方式"):"",style:{marginBottom:0},className:"filter-item",children:(0,C.jsxs)(f.Z,{className:"view-create-modal-sorts",align:"baseline",children:[(0,C.jsx)(m.Z.Item,s()(s()({},a),{},{name:[r,"property"],rules:[{required:!0}],children:L(R)})),(0,C.jsx)(m.Z.Item,s()(s()({},a),{},{name:[r,"type"],rules:[{required:!0}],children:z})),(0,C.jsx)(k.Z,{onClick:function(){return n(r)}})]})},t)})),(0,C.jsx)(m.Z.Item,{children:(0,C.jsxs)("a",{onClick:function(){return a({property:"command",type:"ASC"})},children:[(0,C.jsx)(w.Z,{}),g.ZP.get("新增排序方式")]})}),(0,C.jsx)(m.Z.ErrorList,{errors:i})]})]})}})]})})}},3475:function(e,t,r){var a=r(72317),l=window.__ENV__QlBaseUrl||"/";t.Z={siteName:a.ZP.get("青龙"),baseUrl:l,apiPrefix:"".concat(l,"api/"),authKey:"token",layouts:[{name:"primary",include:[/.*/],exclude:[/(\/(en|zh))*\/login/]}],i18n:{languages:[{key:"pt-br",title:"Português",flag:"/portugal.svg"},{key:"en",title:"English",flag:"/america.svg"},{key:"zh",title:a.ZP.get("中文"),flag:"/china.svg"}],defaultLanguage:"en"},scopes:[{name:a.ZP.get("定时任务"),value:"crons"},{name:a.ZP.get("环境变量"),value:"envs"},{name:a.ZP.get("订阅管理"),value:"subscriptions"},{name:a.ZP.get("配置文件"),value:"configs"},{name:a.ZP.get("脚本管理"),value:"scripts"},{name:a.ZP.get("日志管理"),value:"logs"},{name:a.ZP.get("依赖管理"),value:"dependencies"},{name:a.ZP.get("系统信息"),value:"system"}],scopesMap:{crons:a.ZP.get("定时任务"),envs:a.ZP.get("环境变量"),subscriptions:a.ZP.get("订阅管理"),configs:a.ZP.get("配置文件"),scripts:a.ZP.get("脚本管理"),logs:a.ZP.get("日志管理"),dependencies:a.ZP.get("依赖管理"),system:a.ZP.get("系统信息")},notificationModes:[{value:"gotify",label:"Gotify"},{value:"ntfy",label:"Ntfy"},{value:"goCqHttpBot",label:"GoCqHttpBot"},{value:"serverChan",label:a.ZP.get("Server酱")},{value:"pushDeer",label:"PushDeer"},{value:"bark",label:"Bark"},{value:"telegramBot",label:a.ZP.get("Telegram机器人")},{value:"dingtalkBot",label:a.ZP.get("钉钉机器人")},{value:"weWorkBot",label:a.ZP.get("企业微信机器人")},{value:"weWorkApp",label:a.ZP.get("企业微信应用")},{value:"aibotk",label:a.ZP.get("智能微秘书")},{value:"iGot",label:"IGot"},{value:"pushPlus",label:"PushPlus"},{value:"wePlusBot",label:a.ZP.get("微加机器人")},{value:"wxPusherBot",label:"wxPusher"},{value:"chat",label:a.ZP.get("群晖chat")},{value:"email",label:a.ZP.get("邮箱")},{value:"lark",label:a.ZP.get("飞书机器人")},{value:"pushMe",label:"PushMe"},{value:"chronocat",label:"Chronocat"},{value:"webhook",label:a.ZP.get("自定义通知")},{value:"closed",label:a.ZP.get("已关闭")}],notificationModeMap:{gotify:[{label:"gotifyUrl",tip:a.ZP.get("gotify的url地址,例如 https://push.example.de:8080"),required:!0},{label:"gotifyToken",tip:a.ZP.get("gotify的消息应用token码"),required:!0},{label:"gotifyPriority",tip:a.ZP.get("推送消息的优先级")}],ntfy:[{label:"ntfyUrl",tip:a.ZP.get("ntfy的url地址,例如 https://ntfy.sh"),required:!0},{label:"ntfyTopic",tip:a.ZP.get("ntfy的消息应用topic"),required:!0},{label:"ntfyPriority",tip:a.ZP.get("推送消息的优先级")}],chat:[{label:"synologyChatUrl",tip:a.ZP.get("synologyChat的url地址"),required:!0}],goCqHttpBot:[{label:"goCqHttpBotUrl",tip:a.ZP.get("推送到个人QQ: http://127.0.0.1/send_private_msg,群:http://127.0.0.1/send_group_msg"),required:!0},{label:"goCqHttpBotToken",tip:a.ZP.get("访问密钥"),required:!0},{label:"goCqHttpBotQq",tip:a.ZP.get("如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群"),required:!0}],serverChan:[{label:"serverChanKey",tip:a.ZP.get("Server酱SENDKEY"),required:!0}],pushDeer:[{label:"pushDeerKey",tip:a.ZP.get("PushDeer的Key,https://github.com/easychen/pushdeer"),required:!0},{label:"pushDeerUrl",tip:a.ZP.get("PushDeer的自架API endpoint,默认是 https://api2.pushdeer.com/message/push")}],bark:[{label:"barkPush",tip:a.ZP.get("Bark的信息IP/设备码,例如:https://api.day.app/XXXXXXXX"),required:!0},{label:"barkIcon",tip:a.ZP.get("BARK推送图标,自定义推送图标 (需iOS15或以上才能显示)")},{label:"barkSound",tip:a.ZP.get("BARK推送铃声,铃声列表去APP查看复制填写")},{label:"barkGroup",tip:a.ZP.get("BARK推送消息的分组,默认为qinglong")},{label:"barkLevel",tip:a.ZP.get("BARK推送消息的时效性,默认为active")},{label:"barkUrl",tip:a.ZP.get("BARK推送消息的跳转URL")},{label:"barkArchive",tip:a.ZP.get("BARK是否保存推送消息")}],telegramBot:[{label:"telegramBotToken",tip:a.ZP.get("telegram机器人的token,例如:1077xxx4424:AAFjv0FcqxxxxxxgEMGfi22B4yh15R5uw"),required:!0},{label:"telegramBotUserId",tip:a.ZP.get("telegram用户的id,例如:129xxx206"),required:!0},{label:"telegramBotProxyHost",tip:a.ZP.get("代理IP")},{label:"telegramBotProxyPort",tip:a.ZP.get("代理端口")},{label:"telegramBotProxyAuth",tip:a.ZP.get("telegram代理配置认证参数,用户名与密码用英文冒号连接 user:password")},{label:"telegramBotApiHost",tip:a.ZP.get("telegram api自建的反向代理地址,默认tg官方api")}],dingtalkBot:[{label:"dingtalkBotToken",tip:a.ZP.get("钉钉机器人webhook token,例如:5a544165465465645d0f31dca676e7bd07415asdasd"),required:!0},{label:"dingtalkBotSecret",tip:a.ZP.get("密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串")}],weWorkBot:[{label:"weWorkBotKey",tip:a.ZP.get("企业微信机器人的webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa"),required:!0},{label:"weWorkOrigin",tip:a.ZP.get("企业微信代理地址")}],weWorkApp:[{label:"weWorkAppKey",tip:a.ZP.get("corpid、corpsecret、touser(注:多个成员ID使用|隔开)、agentid、消息类型(选填,不填默认文本消息类型) 注意用,号隔开(英文输入法的逗号),例如:wwcfrs,B-76WERQ,qinglong,1000001,2COat"),required:!0},{label:"weWorkOrigin",tip:a.ZP.get("企业微信代理地址")}],aibotk:[{label:"aibotkKey",tip:a.ZP.get("密钥key,智能微秘书个人中心获取apikey,申请地址:https://wechat.aibotk.com/signup?from=ql"),required:!0},{label:"aibotkType",tip:a.ZP.get("发送的目标,群组或者好友"),required:!0,placeholder:a.ZP.get("请输入要发送的目标"),items:[{value:"room",label:a.ZP.get("群聊")},{value:"contact",label:a.ZP.get("好友")}]},{label:"aibotkName",tip:a.ZP.get("要发送的用户昵称或群名,如果目标是群,需要填群名,如果目标是好友,需要填好友昵称"),required:!0}],iGot:[{label:"iGotPushKey",tip:a.ZP.get("iGot的信息推送key,例如:https://push.hellyw.com/XXXXXXXX"),required:!0}],pushPlus:[{label:"pushPlusToken",tip:a.ZP.get("微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送,参考 https://www.pushplus.plus/"),required:!0},{label:"pushPlusUser",tip:a.ZP.get("一对多推送的“群组编码”(一对多推送下面->您的群组(如无则创建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)")},{label:"pushplusTemplate",tip:a.ZP.get("发送模板")},{label:"pushplusChannel",tip:a.ZP.get("发送渠道")},{label:"pushplusWebhook",tip:a.ZP.get("webhook编码")},{label:"pushplusCallbackUrl",tip:a.ZP.get("发送结果回调地址")},{label:"pushplusTo",tip:a.ZP.get("好友令牌")}],wePlusBot:[{label:"wePlusBotToken",tip:a.ZP.get("用户令牌,扫描登录后 我的—>设置->令牌 中获取,参考 https://www.weplusbot.com/"),required:!0},{label:"wePlusBotReceiver",tip:a.ZP.get("消息接收人")},{label:"wePlusBotVersion",tip:a.ZP.get("调用版本;专业版填写pro,个人版填写personal,为空默认使用专业版")}],wxPusherBot:[{label:"wxPusherBotAppToken",tip:a.ZP.get("wxPusherBot的appToken"),required:!0},{label:"wxPusherBotTopicIds",tip:a.ZP.get("wxPusherBot的topicIds"),required:!1},{label:"wxPusherBotUids",tip:a.ZP.get("wxPusherBot的uids"),required:!1}],lark:[{label:"larkKey",tip:a.ZP.get("飞书群组机器人:https://www.feishu.cn/hc/zh-CN/articles/360024984973"),required:!0}],email:[{label:"emailService",tip:a.ZP.get("邮箱服务名称,比如126、163、Gmail、QQ等,支持列表https://github.com/nodemailer/nodemailer/blob/master/lib/well-known/services.json"),required:!0},{label:"emailUser",tip:a.ZP.get("邮箱地址"),required:!0},{label:"emailPass",tip:a.ZP.get("SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定"),required:!0}],pushMe:[{label:"pushMeKey",tip:a.ZP.get("PushMe的Key,https://push.i-i.me/"),required:!0},{label:"pushMeUrl",tip:a.ZP.get("自建的PushMeServer消息接口地址,例如:http://127.0.0.1:3010,不填则使用官方消息接口"),required:!1}],chronocat:[{label:"chronocatURL",tip:a.ZP.get("Chronocat Red 服务的连接地址 https://chronocat.vercel.app/install/docker/official/"),required:!0},{label:"chronocatQQ",tip:a.ZP.get("个人:user_id=个人QQ 群则填入group_id=QQ群 多个用英文;隔开同时支持个人和群 如:user_id=xxx;group_id=xxxx;group_id=xxxxx"),required:!0},{label:"chronocatToken",tip:a.ZP.get("docker安装在持久化config目录下的chronocat.yml文件可找到"),required:!0}],webhook:[{label:"webhookMethod",tip:a.ZP.get("请求方法"),required:!0,items:[{value:"GET"},{value:"POST"},{value:"PUT"}]},{label:"webhookContentType",tip:a.ZP.get("请求头Content-Type"),required:!0,items:[{value:"text/plain"},{value:"application/json"},{value:"multipart/form-data"},{value:"application/x-www-form-urlencoded"}]},{label:"webhookUrl",tip:a.ZP.get("请求链接以http或者https开头。url或者body中必须包含$title,$content可选,对应api内容的位置"),required:!0,placeholder:"https://xxx.cn/api?content=$title\n"},{label:"webhookHeaders",tip:a.ZP.get("请求头格式Custom-Header1: Header1,多个换行分割"),placeholder:"Custom-Header1: Header1\nCustom-Header2: Header2"},{label:"webhookBody",tip:a.ZP.get("请求体格式key1: value1,多个换行分割。url或者body中必须包含$title,$content可选,对应api内容的位置"),placeholder:"key1: $title\nkey2: $content"}]},documentTitleMap:{"/login":a.ZP.get("登录"),"/initialization":a.ZP.get("初始化"),"/crontab":a.ZP.get("定时任务"),"/env":a.ZP.get("环境变量"),"/subscription":a.ZP.get("订阅管理"),"/config":a.ZP.get("配置文件"),"/script":a.ZP.get("脚本管理"),"/diff":a.ZP.get("对比工具"),"/log":a.ZP.get("日志管理"),"/setting":a.ZP.get("系统设置"),"/error":a.ZP.get("错误日志"),"/dependence":a.ZP.get("依赖管理")},dependenceTypes:["nodejs","python3","linux"]}},16314:function(e,t,r){r.d(t,{W:function(){return Z}});var a=r(90228),l=r.n(a),n=r(87999),i=r.n(n),o=r(72317),s=r(61508),u=r(33839),p=r(3475),c=r(98783),d=r(69313),g=r(52676);s.ZP.config({duration:2});var h=Date.now(),m=d.Z.create({timeout:6e4,params:{t:h}}),P=["/api/user/login","/open/auth/token","/api/user/two-factor/login","/api/system","/api/user/init","/api/user/notification/init"];m.interceptors.request.use((function(e){var t=localStorage.getItem(p.Z.authKey);return t&&!P.includes(e.url)?(e.headers.Authorization="Bearer ".concat(t),e):e})),m.interceptors.response.use(function(){var e=i()(l()().mark((function e(t){var r,a,n;return l()().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=t.status,![502,504].includes(r)){e.next=5;break}c.history.push("/error"),e.next=18;break;case 5:if(401!==r){e.next=9;break}"/login"!==c.history.location.pathname&&(localStorage.removeItem(p.Z.authKey),c.history.push("/login")),e.next=18;break;case 9:return e.prev=9,200!==(a=t.data).code&&(n=a.message||a.data)&&u.Z.error({message:n,description:null!=a&&a.errors?(0,g.jsx)(g.Fragment,{children:null==a?void 0:a.errors.map((function(e){return(0,g.jsx)("div",{children:e.message})}))}):void 0}),e.abrupt("return",a);case 15:e.prev=15,e.t0=e.catch(9);case 17:case 18:return e.abrupt("return",t);case 19:case"end":return e.stop()}}),e,null,[[9,15]])})));return function(t){return e.apply(this,arguments)}}(),(function(e){if(e.response){var t=e.response.data?e.response.data.message||e.message:e.response.statusText,r=e.response.status;if([502,504].includes(r))c.history.push("/error");else if(401===r)"/login"!==c.history.location.pathname&&(s.ZP.error(o.ZP.get("登录已过期,请重新登录")),localStorage.removeItem(p.Z.authKey),c.history.push("/login"));else{var a,l,n,i;if("function"==typeof(null===(a=e.config)||void 0===a?void 0:a.onError))return null===(i=e.config)||void 0===i?void 0:i.onError(e.response);t&&u.Z.error({message:t,description:null!==(l=e.response)&&void 0!==l&&null!==(l=l.data)&&void 0!==l&&l.errors?(0,g.jsx)(g.Fragment,{children:null===(n=e.response)||void 0===n||null===(n=n.data)||void 0===n||null===(n=n.errors)||void 0===n?void 0:n.map((function(e){return(0,g.jsxs)("div",{children:[e.message," (",e.value,")"]})}))}):void 0})}}else console.log(e.message);return Promise.reject(e)}));var Z=m}}]);
1
+ "use strict";(self.webpackChunk_whyour_qinglong=self.webpackChunk_whyour_qinglong||[]).push([[2208,5812],{44224:function(e,t,r){var a=(0,r(19919).Z)({scriptUrl:["//at.alicdn.com/t/c/font_3354854_lc939gab1iq.js"]});t.Z=a},44860:function(e,t,r){r.r(t),r.d(t,{CrontabStatus:function(){return a},OperationName:function(){return l},OperationPath:function(){return n},ScheduleType:function(){return i}});var a=function(e){return e[e.running=0]="running",e[e.queued=.5]="queued",e[e.idle=1]="idle",e[e.disabled=2]="disabled",e}({}),l=function(e){return e[e["启用"]=0]="启用",e[e["禁用"]=1]="禁用",e[e["运行"]=2]="运行",e[e["停止"]=3]="停止",e[e["置顶"]=4]="置顶",e[e["取消置顶"]=5]="取消置顶",e}({}),n=function(e){return e[e.enable=0]="enable",e[e.disable=1]="disable",e[e.run=2]="run",e[e.stop=3]="stop",e[e.pin=4]="pin",e[e.unpin=5]="unpin",e}({}),i=function(e){return e.Normal="normal",e.Once="once",e.Boot="boot",e}({})},42208:function(e,t,r){r.r(t);var a=r(67825),l=r.n(a),n=r(90228),i=r.n(n),o=r(26068),s=r.n(o),u=r(87999),p=r.n(u),c=r(48305),d=r.n(c),g=r(72317),h=r(75271),m=r(72338),P=r(35181),Z=r(45520),b=r(17082),v=r(93481),f=r(63505),x=r(16314),y=r(3475),k=r(37559),w=r(21288),q=r(44224),j=r(44860),B=r(31352),C=r(52676),_=["name"],S=["key","name"],T=["key","name"],R=[{name:g.ZP.get("命令"),value:"command"},{name:g.ZP.get("名称"),value:"name"},{name:g.ZP.get("定时规则"),value:"schedule"},{name:g.ZP.get("状态"),value:"status",onlySelect:!0},{name:g.ZP.get("标签"),value:"labels"},{name:g.ZP.get("订阅"),value:"sub_id",onlySelect:!0}],I={Reg:"",NotReg:"",In:"select",Nin:"select"},U=[{name:g.ZP.get("包含"),value:"Reg"},{name:g.ZP.get("不包含"),value:"NotReg"},{name:g.ZP.get("属于"),value:"In",type:"select"},{name:g.ZP.get("不属于"),value:"Nin",type:"select"}],K=[{name:g.ZP.get("顺序"),value:"ASC"},{name:g.ZP.get("倒序"),value:"DESC"}],A=function(e){return e.and="且",e.or="或",e}(A||{});t.default=function(e){var t=e.view,r=e.handleCancel,a=e.visible,n=m.Z.useForm(),o=d()(n,1)[0],u=(0,h.useState)(!1),c=d()(u,2),N=c[0],Q=c[1],H=(0,h.useState)("and"),X=d()(H,2),E=X[0],M=X[1],O=m.Z.useWatch("filters",o),W=(0,B.Z)((function(){return x.W.get("".concat(y.Z.apiPrefix,"subscriptions"))}),{cacheKey:"subscriptions"}).data,F={status:[{name:g.ZP.get("运行中"),value:j.CrontabStatus.running},{name:g.ZP.get("空闲中"),value:j.CrontabStatus.idle},{name:g.ZP.get("已禁用"),value:j.CrontabStatus.disabled}],sub_id:null==W?void 0:W.data.map((function(e){return{name:e.name,value:e.id}}))},G=function(){var e=p()(i()().mark((function e(a){var l,n,o,u;return i()().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return Q(!0),a.filterRelation=E,l=t?"put":"post",e.prev=3,e.next=6,x.W[l]("".concat(y.Z.apiPrefix,"crons/views"),t?s()(s()({},a),{},{id:t.id}):a);case 6:n=e.sent,o=n.code,u=n.data,200===o&&r(u),Q(!1),e.next=16;break;case 13:e.prev=13,e.t0=e.catch(3),Q(!1);case 16:case"end":return e.stop()}}),e,null,[[3,13]])})));return function(t){return e.apply(this,arguments)}}();(0,h.useEffect)((function(){t||o.resetFields(),o.setFieldsValue(t||{filters:[{property:"command"}]})}),[t,a]);var D=function(e){var t=e.name,r=l()(e,_),a=o.getFieldValue(["filters",t,"property"]);return(0,C.jsx)(P.Z,s()(s()({style:{width:120},placeholder:g.ZP.get("请选择操作符")},r),{},{children:U.filter((function(e){return F[a]?"select"===e.type:e})).map((function(e){return(0,C.jsx)(P.Z.Option,{value:e.value,children:e.name},e.name)}))}))},L=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return(0,C.jsx)(P.Z,{style:t,children:e.map((function(e){return(0,C.jsx)(P.Z.Option,{value:e.value,children:e.name},e.name)}))})},z=(0,C.jsx)(P.Z,{style:{width:80},children:K.map((function(e){return(0,C.jsx)(P.Z.Option,{value:e.value,children:e.name},e.name)}))});return(0,C.jsx)(Z.Z,{title:t?g.ZP.get("编辑视图"):g.ZP.get("创建视图"),open:a,forceRender:!0,width:580,centered:!0,maskClosable:!1,onOk:function(){o.validateFields().then((function(e){G(e)})).catch((function(e){console.log("Validate Failed:",e)}))},onCancel:function(){return r()},confirmLoading:N,children:(0,C.jsxs)(m.Z,{form:o,layout:"vertical",name:"env_modal",children:[(0,C.jsx)(m.Z.Item,{name:"name",label:g.ZP.get("视图名称"),rules:[{required:!0,message:g.ZP.get("请输入视图名称")}],children:(0,C.jsx)(b.Z,{placeholder:g.ZP.get("请输入视图名称")})}),(0,C.jsx)(m.Z.List,{name:"filters",children:function(e,t,r){var a=t.add,n=t.remove,i=r.errors;return(0,C.jsxs)("div",{style:{position:"relative"},className:"view-filters-container ".concat(e.length>1?"active":""),children:[e.length>1&&(0,C.jsx)("div",{style:{position:"absolute",width:50,borderRadius:10,border:"1px solid rgb(190, 220, 255)",borderRight:"none",height:56*(e.length-1),top:46,left:15},children:(0,C.jsx)(v.Z,{type:"primary",size:"small",style:{position:"absolute",top:"50%",translate:"-50% -50%",padding:"0 3px",cursor:"pointer"},onClick:function(){M("and"===E?"or":"and")},children:(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)("span",{children:A[E]}),(0,C.jsx)(q.Z,{type:"ql-icon-d-caret"})]})})}),(0,C.jsxs)("div",{children:[e.map((function(e){var t,r,a=e.key,i=e.name,o=l()(e,S);return(0,C.jsx)(m.Z.Item,{label:0===i?g.ZP.get("筛选条件"):"",style:{marginBottom:0},required:!0,className:"filter-item",children:(0,C.jsxs)(f.Z,{className:"view-create-modal-filters",align:"baseline",children:[(0,C.jsx)(m.Z.Item,s()(s()({},o),{},{name:[i,"property"],rules:[{required:!0}],children:L(R,{width:120})})),(0,C.jsx)(m.Z.Item,s()(s()({},o),{},{name:[i,"operation"],rules:[{required:!0,message:g.ZP.get("请选择操作符")}],children:(0,C.jsx)(D,{name:i})})),(0,C.jsx)(m.Z.Item,s()(s()({},o),{},{name:[i,"value"],rules:[{required:!0,message:g.ZP.get("请输入内容")}],children:"select"===I[null==O?void 0:O[i].operation]?(t=null==O?void 0:O[i].property,(0,C.jsx)(P.Z,{mode:"tags",allowClear:!0,placeholder:g.ZP.get("输入后回车增加自定义选项"),children:null===(r=F[t])||void 0===r?void 0:r.map((function(e){return(0,C.jsx)(P.Z.Option,{value:e.value,children:e.name},e.name)}))})):(0,C.jsx)(b.Z,{placeholder:g.ZP.get("请输入内容")})})),0!==i&&(0,C.jsx)(k.Z,{onClick:function(){return n(i)}})]})},a)})),(0,C.jsx)(m.Z.Item,{children:(0,C.jsxs)("a",{onClick:function(){return a({property:"command",operation:"Reg"})},children:[(0,C.jsx)(w.Z,{}),g.ZP.get("新增筛选条件")]})}),(0,C.jsx)(m.Z.ErrorList,{errors:i})]})]})}}),(0,C.jsx)(m.Z.List,{name:"sorts",children:function(e,t,r){var a=t.add,n=t.remove,i=r.errors;return(0,C.jsxs)("div",{style:{position:"relative"},className:"view-filters-container ".concat(e.length>1?"active":""),children:[e.length>1&&(0,C.jsx)("div",{style:{position:"absolute",width:50,borderRadius:10,border:"1px solid rgb(190, 220, 255)",borderRight:"none",height:56*(e.length-1),top:46,left:15},children:(0,C.jsx)(v.Z,{type:"primary",size:"small",style:{position:"absolute",top:"50%",translate:"-50% -50%",padding:"0 3px",cursor:"pointer"},children:(0,C.jsx)(C.Fragment,{children:(0,C.jsx)("span",{children:A[E]})})})}),(0,C.jsxs)("div",{children:[e.map((function(e){var t=e.key,r=e.name,a=l()(e,T);return(0,C.jsx)(m.Z.Item,{label:0===r?g.ZP.get("排序方式"):"",style:{marginBottom:0},className:"filter-item",children:(0,C.jsxs)(f.Z,{className:"view-create-modal-sorts",align:"baseline",children:[(0,C.jsx)(m.Z.Item,s()(s()({},a),{},{name:[r,"property"],rules:[{required:!0}],children:L(R)})),(0,C.jsx)(m.Z.Item,s()(s()({},a),{},{name:[r,"type"],rules:[{required:!0}],children:z})),(0,C.jsx)(k.Z,{onClick:function(){return n(r)}})]})},t)})),(0,C.jsx)(m.Z.Item,{children:(0,C.jsxs)("a",{onClick:function(){return a({property:"command",type:"ASC"})},children:[(0,C.jsx)(w.Z,{}),g.ZP.get("新增排序方式")]})}),(0,C.jsx)(m.Z.ErrorList,{errors:i})]})]})}})]})})}},3475:function(e,t,r){var a=r(72317),l=window.__ENV__QlBaseUrl||"/";t.Z={siteName:a.ZP.get("青龙"),baseUrl:l,apiPrefix:"".concat(l,"api/"),authKey:"token",layouts:[{name:"primary",include:[/.*/],exclude:[/(\/(en|zh))*\/login/]}],i18n:{languages:[{key:"pt-br",title:"Português",flag:"/portugal.svg"},{key:"en",title:"English",flag:"/america.svg"},{key:"zh",title:a.ZP.get("中文"),flag:"/china.svg"}],defaultLanguage:"en"},scopes:[{name:a.ZP.get("定时任务"),value:"crons"},{name:a.ZP.get("环境变量"),value:"envs"},{name:a.ZP.get("订阅管理"),value:"subscriptions"},{name:a.ZP.get("配置文件"),value:"configs"},{name:a.ZP.get("脚本管理"),value:"scripts"},{name:a.ZP.get("日志管理"),value:"logs"},{name:a.ZP.get("依赖管理"),value:"dependencies"},{name:a.ZP.get("系统信息"),value:"system"}],scopesMap:{crons:a.ZP.get("定时任务"),envs:a.ZP.get("环境变量"),subscriptions:a.ZP.get("订阅管理"),configs:a.ZP.get("配置文件"),scripts:a.ZP.get("脚本管理"),logs:a.ZP.get("日志管理"),dependencies:a.ZP.get("依赖管理"),system:a.ZP.get("系统信息")},notificationModes:[{value:"gotify",label:"Gotify"},{value:"ntfy",label:"Ntfy"},{value:"goCqHttpBot",label:"GoCqHttpBot"},{value:"serverChan",label:a.ZP.get("Server酱")},{value:"pushDeer",label:"PushDeer"},{value:"bark",label:"Bark"},{value:"telegramBot",label:a.ZP.get("Telegram机器人")},{value:"dingtalkBot",label:a.ZP.get("钉钉机器人")},{value:"weWorkBot",label:a.ZP.get("企业微信机器人")},{value:"weWorkApp",label:a.ZP.get("企业微信应用")},{value:"aibotk",label:a.ZP.get("智能微秘书")},{value:"iGot",label:"IGot"},{value:"pushPlus",label:"PushPlus"},{value:"wePlusBot",label:a.ZP.get("微加机器人")},{value:"wxPusherBot",label:"wxPusher"},{value:"chat",label:a.ZP.get("群晖chat")},{value:"email",label:a.ZP.get("邮箱")},{value:"lark",label:a.ZP.get("飞书机器人")},{value:"pushMe",label:"PushMe"},{value:"chronocat",label:"Chronocat"},{value:"webhook",label:a.ZP.get("自定义通知")},{value:"closed",label:a.ZP.get("已关闭")}],notificationModeMap:{gotify:[{label:"gotifyUrl",tip:a.ZP.get("gotify的url地址,例如 https://push.example.de:8080"),required:!0},{label:"gotifyToken",tip:a.ZP.get("gotify的消息应用token码"),required:!0},{label:"gotifyPriority",tip:a.ZP.get("推送消息的优先级")}],ntfy:[{label:"ntfyUrl",tip:a.ZP.get("ntfy的url地址,例如 https://ntfy.sh"),required:!0},{label:"ntfyTopic",tip:a.ZP.get("ntfy的消息应用topic"),required:!0},{label:"ntfyPriority",tip:a.ZP.get("推送消息的优先级")}],chat:[{label:"synologyChatUrl",tip:a.ZP.get("synologyChat的url地址"),required:!0}],goCqHttpBot:[{label:"goCqHttpBotUrl",tip:a.ZP.get("推送到个人QQ: http://127.0.0.1/send_private_msg,群:http://127.0.0.1/send_group_msg"),required:!0},{label:"goCqHttpBotToken",tip:a.ZP.get("访问密钥"),required:!0},{label:"goCqHttpBotQq",tip:a.ZP.get("如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群"),required:!0}],serverChan:[{label:"serverChanKey",tip:a.ZP.get("Server酱SENDKEY"),required:!0}],pushDeer:[{label:"pushDeerKey",tip:a.ZP.get("PushDeer的Key,https://github.com/easychen/pushdeer"),required:!0},{label:"pushDeerUrl",tip:a.ZP.get("PushDeer的自架API endpoint,默认是 https://api2.pushdeer.com/message/push")}],bark:[{label:"barkPush",tip:a.ZP.get("Bark的信息IP/设备码,例如:https://api.day.app/XXXXXXXX"),required:!0},{label:"barkIcon",tip:a.ZP.get("BARK推送图标,自定义推送图标 (需iOS15或以上才能显示)")},{label:"barkSound",tip:a.ZP.get("BARK推送铃声,铃声列表去APP查看复制填写")},{label:"barkGroup",tip:a.ZP.get("BARK推送消息的分组,默认为qinglong")},{label:"barkLevel",tip:a.ZP.get("BARK推送消息的时效性,默认为active")},{label:"barkUrl",tip:a.ZP.get("BARK推送消息的跳转URL")},{label:"barkArchive",tip:a.ZP.get("BARK是否保存推送消息")}],telegramBot:[{label:"telegramBotToken",tip:a.ZP.get("telegram机器人的token,例如:1077xxx4424:AAFjv0FcqxxxxxxgEMGfi22B4yh15R5uw"),required:!0},{label:"telegramBotUserId",tip:a.ZP.get("telegram用户的id,例如:129xxx206"),required:!0},{label:"telegramBotProxyHost",tip:a.ZP.get("代理IP")},{label:"telegramBotProxyPort",tip:a.ZP.get("代理端口")},{label:"telegramBotProxyAuth",tip:a.ZP.get("telegram代理配置认证参数,用户名与密码用英文冒号连接 user:password")},{label:"telegramBotApiHost",tip:a.ZP.get("telegram api自建的反向代理地址,默认tg官方api")}],dingtalkBot:[{label:"dingtalkBotToken",tip:a.ZP.get("钉钉机器人webhook token,例如:5a544165465465645d0f31dca676e7bd07415asdasd"),required:!0},{label:"dingtalkBotSecret",tip:a.ZP.get("密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串")}],weWorkBot:[{label:"weWorkBotKey",tip:a.ZP.get("企业微信机器人的webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa"),required:!0},{label:"weWorkOrigin",tip:a.ZP.get("企业微信代理地址")}],weWorkApp:[{label:"weWorkAppKey",tip:a.ZP.get("corpid、corpsecret、touser(注:多个成员ID使用|隔开)、agentid、消息类型(选填,不填默认文本消息类型) 注意用,号隔开(英文输入法的逗号),例如:wwcfrs,B-76WERQ,qinglong,1000001,2COat"),required:!0},{label:"weWorkOrigin",tip:a.ZP.get("企业微信代理地址")}],aibotk:[{label:"aibotkKey",tip:a.ZP.get("密钥key,智能微秘书个人中心获取apikey,申请地址:https://wechat.aibotk.com/signup?from=ql"),required:!0},{label:"aibotkType",tip:a.ZP.get("发送的目标,群组或者好友"),required:!0,placeholder:a.ZP.get("请输入要发送的目标"),items:[{value:"room",label:a.ZP.get("群聊")},{value:"contact",label:a.ZP.get("好友")}]},{label:"aibotkName",tip:a.ZP.get("要发送的用户昵称或群名,如果目标是群,需要填群名,如果目标是好友,需要填好友昵称"),required:!0}],iGot:[{label:"iGotPushKey",tip:a.ZP.get("iGot的信息推送key,例如:https://push.hellyw.com/XXXXXXXX"),required:!0}],pushPlus:[{label:"pushPlusToken",tip:a.ZP.get("微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送,参考 https://www.pushplus.plus/"),required:!0},{label:"pushPlusUser",tip:a.ZP.get("一对多推送的“群组编码”(一对多推送下面->您的群组(如无则创建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)")},{label:"pushplusTemplate",tip:a.ZP.get("发送模板")},{label:"pushplusChannel",tip:a.ZP.get("发送渠道")},{label:"pushplusWebhook",tip:a.ZP.get("webhook编码")},{label:"pushplusCallbackUrl",tip:a.ZP.get("发送结果回调地址")},{label:"pushplusTo",tip:a.ZP.get("好友令牌")}],wePlusBot:[{label:"wePlusBotToken",tip:a.ZP.get("用户令牌,扫描登录后 我的—>设置->令牌 中获取,参考 https://www.weplusbot.com/"),required:!0},{label:"wePlusBotReceiver",tip:a.ZP.get("消息接收人")},{label:"wePlusBotVersion",tip:a.ZP.get("调用版本;专业版填写pro,个人版填写personal,为空默认使用专业版")}],wxPusherBot:[{label:"wxPusherBotAppToken",tip:a.ZP.get("wxPusherBot的appToken"),required:!0},{label:"wxPusherBotTopicIds",tip:a.ZP.get("wxPusherBot的topicIds"),required:!1},{label:"wxPusherBotUids",tip:a.ZP.get("wxPusherBot的uids"),required:!1}],lark:[{label:"larkKey",tip:a.ZP.get("飞书群组机器人:https://www.feishu.cn/hc/zh-CN/articles/360024984973"),required:!0}],email:[{label:"emailService",tip:a.ZP.get("邮箱服务名称,比如126、163、Gmail、QQ等,支持列表https://github.com/nodemailer/nodemailer/blob/master/lib/well-known/services.json"),required:!0},{label:"emailUser",tip:a.ZP.get("邮箱认证地址"),required:!0},{label:"emailPass",tip:a.ZP.get("SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定"),required:!0},{label:"emailTo",tip:a.ZP.get("收件邮箱地址,多个分号分隔,默认发送给发件邮箱地址")}],pushMe:[{label:"pushMeKey",tip:a.ZP.get("PushMe的Key,https://push.i-i.me/"),required:!0},{label:"pushMeUrl",tip:a.ZP.get("自建的PushMeServer消息接口地址,例如:http://127.0.0.1:3010,不填则使用官方消息接口"),required:!1}],chronocat:[{label:"chronocatURL",tip:a.ZP.get("Chronocat Red 服务的连接地址 https://chronocat.vercel.app/install/docker/official/"),required:!0},{label:"chronocatQQ",tip:a.ZP.get("个人:user_id=个人QQ 群则填入group_id=QQ群 多个用英文;隔开同时支持个人和群 如:user_id=xxx;group_id=xxxx;group_id=xxxxx"),required:!0},{label:"chronocatToken",tip:a.ZP.get("docker安装在持久化config目录下的chronocat.yml文件可找到"),required:!0}],webhook:[{label:"webhookMethod",tip:a.ZP.get("请求方法"),required:!0,items:[{value:"GET"},{value:"POST"},{value:"PUT"}]},{label:"webhookContentType",tip:a.ZP.get("请求头Content-Type"),required:!0,items:[{value:"text/plain"},{value:"application/json"},{value:"multipart/form-data"},{value:"application/x-www-form-urlencoded"}]},{label:"webhookUrl",tip:a.ZP.get("请求链接以http或者https开头。url或者body中必须包含$title,$content可选,对应api内容的位置"),required:!0,placeholder:"https://xxx.cn/api?content=$title\n"},{label:"webhookHeaders",tip:a.ZP.get("请求头格式Custom-Header1: Header1,多个换行分割"),placeholder:"Custom-Header1: Header1\nCustom-Header2: Header2"},{label:"webhookBody",tip:a.ZP.get("请求体格式key1: value1,多个换行分割。url或者body中必须包含$title,$content可选,对应api内容的位置"),placeholder:"key1: $title\nkey2: $content"}]},documentTitleMap:{"/login":a.ZP.get("登录"),"/initialization":a.ZP.get("初始化"),"/crontab":a.ZP.get("定时任务"),"/env":a.ZP.get("环境变量"),"/subscription":a.ZP.get("订阅管理"),"/config":a.ZP.get("配置文件"),"/script":a.ZP.get("脚本管理"),"/diff":a.ZP.get("对比工具"),"/log":a.ZP.get("日志管理"),"/setting":a.ZP.get("系统设置"),"/error":a.ZP.get("错误日志"),"/dependence":a.ZP.get("依赖管理")},dependenceTypes:["nodejs","python3","linux"]}},16314:function(e,t,r){r.d(t,{W:function(){return Z}});var a=r(90228),l=r.n(a),n=r(87999),i=r.n(n),o=r(72317),s=r(61508),u=r(33839),p=r(3475),c=r(98783),d=r(69313),g=r(52676);s.ZP.config({duration:2});var h=Date.now(),m=d.Z.create({timeout:6e4,params:{t:h}}),P=["/api/user/login","/open/auth/token","/api/user/two-factor/login","/api/system","/api/user/init","/api/user/notification/init"];m.interceptors.request.use((function(e){var t=localStorage.getItem(p.Z.authKey);return t&&!P.includes(e.url)?(e.headers.Authorization="Bearer ".concat(t),e):e})),m.interceptors.response.use(function(){var e=i()(l()().mark((function e(t){var r,a,n;return l()().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=t.status,![502,504].includes(r)){e.next=5;break}c.history.push("/error"),e.next=18;break;case 5:if(401!==r){e.next=9;break}"/login"!==c.history.location.pathname&&(localStorage.removeItem(p.Z.authKey),c.history.push("/login")),e.next=18;break;case 9:return e.prev=9,200!==(a=t.data).code&&(n=a.message||a.data)&&u.Z.error({message:n,description:null!=a&&a.errors?(0,g.jsx)(g.Fragment,{children:null==a?void 0:a.errors.map((function(e){return(0,g.jsx)("div",{children:e.message})}))}):void 0}),e.abrupt("return",a);case 15:e.prev=15,e.t0=e.catch(9);case 17:case 18:return e.abrupt("return",t);case 19:case"end":return e.stop()}}),e,null,[[9,15]])})));return function(t){return e.apply(this,arguments)}}(),(function(e){if(e.response){var t=e.response.data?e.response.data.message||e.message:e.response.statusText,r=e.response.status;if([502,504].includes(r))c.history.push("/error");else if(401===r)"/login"!==c.history.location.pathname&&(s.ZP.error(o.ZP.get("登录已过期,请重新登录")),localStorage.removeItem(p.Z.authKey),c.history.push("/login"));else{var a,l,n,i;if("function"==typeof(null===(a=e.config)||void 0===a?void 0:a.onError))return null===(i=e.config)||void 0===i?void 0:i.onError(e.response);t&&u.Z.error({message:t,description:null!==(l=e.response)&&void 0!==l&&null!==(l=l.data)&&void 0!==l&&l.errors?(0,g.jsx)(g.Fragment,{children:null===(n=e.response)||void 0===n||null===(n=n.data)||void 0===n||null===(n=n.errors)||void 0===n?void 0:n.map((function(e){return(0,g.jsxs)("div",{children:[e.message," (",e.value,")"]})}))}):void 0})}}else console.log(e.message);return Promise.reject(e)}));var Z=m}}]);