@whyour/qinglong 2.21.0-1 → 2.21.0-3

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 (46) hide show
  1. package/package.json +1 -1
  2. package/static/build/api/cron.js +2 -2
  3. package/static/build/api/dashboard.js +13 -6
  4. package/static/build/config/index.js +0 -4
  5. package/static/build/config/util.js +3 -3
  6. package/static/build/data/sock.js +1 -0
  7. package/static/build/loaders/initTask.js +3 -2
  8. package/static/build/services/cron.js +8 -5
  9. package/static/build/services/dependence.js +19 -18
  10. package/static/build/services/notify.js +5 -5
  11. package/static/build/services/subscription.js +6 -4
  12. package/static/build/services/system.js +12 -2
  13. package/static/build/services/user.js +28 -6
  14. package/static/build/shared/i18n.js +45 -1
  15. package/static/build/shared/pLimit.js +3 -2
  16. package/static/dist/3191.37d489cf.async.js +1 -0
  17. package/static/dist/8826.6879b271.async.js +1 -0
  18. package/static/dist/index.html +2 -2
  19. package/static/dist/{preload_helper.0431c0f3.js → preload_helper.62e0889d.js} +1 -1
  20. package/static/dist/{src__pages__crontab__detail.b9c36808.async.js → src__pages__crontab__detail.cf4a6aaf.async.js} +1 -1
  21. package/static/dist/src__pages__crontab__index.5b67b1a2.async.js +1 -0
  22. package/static/dist/{src__pages__crontab__logModal.0b8cce8c.async.js → src__pages__crontab__logModal.831d5e4b.async.js} +1 -1
  23. package/static/dist/src__pages__dashboard__index.58177357.async.js +1 -0
  24. package/static/dist/src__pages__dependence__index.b7bbc795.async.js +1 -0
  25. package/static/dist/src__pages__env__index.9a565d2b.async.js +1 -0
  26. package/static/dist/src__pages__log__index.9c66639f.async.js +1 -0
  27. package/static/dist/src__pages__script__index.e869812f.async.js +1 -0
  28. package/static/dist/src__pages__setting__checkUpdate.34d773f2.async.js +1 -0
  29. package/static/dist/src__pages__setting__dependence.29f13e8c.async.js +1 -0
  30. package/static/dist/src__pages__setting__index.7a39d415.async.js +1 -0
  31. package/static/dist/src__pages__setting__other.707cfafe.async.js +1 -0
  32. package/static/dist/src__pages__setting__systemLog.1a5c855f.async.js +1 -0
  33. package/static/dist/{umi.ca04a019.js → umi.f5c92fe8.js} +1 -1
  34. package/static/dist/3191.63263871.async.js +0 -1
  35. package/static/dist/8826.2447a104.async.js +0 -1
  36. package/static/dist/src__pages__crontab__index.fed99fd0.async.js +0 -1
  37. package/static/dist/src__pages__dashboard__index.b30f2f47.async.js +0 -1
  38. package/static/dist/src__pages__dependence__index.3d87ceac.async.js +0 -1
  39. package/static/dist/src__pages__env__index.baa27d4e.async.js +0 -1
  40. package/static/dist/src__pages__log__index.e0978bae.async.js +0 -1
  41. package/static/dist/src__pages__script__index.2765d1b8.async.js +0 -1
  42. package/static/dist/src__pages__setting__checkUpdate.46efe057.async.js +0 -1
  43. package/static/dist/src__pages__setting__dependence.8a7a9529.async.js +0 -1
  44. package/static/dist/src__pages__setting__index.cc85fdfb.async.js +0 -1
  45. package/static/dist/src__pages__setting__other.b22d2165.async.js +0 -1
  46. package/static/dist/src__pages__setting__systemLog.67406721.async.js +0 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@whyour/qinglong",
3
3
  "packageManager": "pnpm@8.3.1",
4
- "version": "2.21.0-1",
4
+ "version": "2.21.0-3",
5
5
  "description": "Timed task management platform supporting Python3, JavaScript, Shell, Typescript",
6
6
  "repository": {
7
7
  "type": "git",
@@ -247,8 +247,8 @@ exports.default = (app) => {
247
247
  const logger = typedi_1.Container.get('logger');
248
248
  try {
249
249
  const cronService = typedi_1.Container.get(cron_1.default);
250
- const data = await cronService.log(req.params.id);
251
- return res.send({ code: 200, data });
250
+ const result = await cronService.log(req.params.id);
251
+ return res.send({ code: 200, data: result.content, logStatus: result.status });
252
252
  }
253
253
  catch (e) {
254
254
  return next(e);
@@ -10,6 +10,8 @@ const cronStats_1 = require("../data/cronStats");
10
10
  const runningInstance_1 = require("../data/runningInstance");
11
11
  const dayjs_1 = __importDefault(require("dayjs"));
12
12
  const os_1 = __importDefault(require("os"));
13
+ const lodash_1 = require("lodash");
14
+ const i18n_1 = require("../shared/i18n");
13
15
  const route = (0, express_1.Router)();
14
16
  exports.default = (app) => {
15
17
  app.use('/dashboard', route);
@@ -153,7 +155,7 @@ exports.default = (app) => {
153
155
  crons.forEach((c) => { nameMap[c.id] = c.name || c.command; });
154
156
  const data = rows.map((r, i) => ({
155
157
  rank: i + 1,
156
- name: nameMap[Number(r.ref_id)] || `任务#${r.ref_id}`,
158
+ name: nameMap[Number(r.ref_id)] || (0, i18n_1.tf)('任务#%s', r.ref_id),
157
159
  avgTime: Math.round(Number(r.total_time) / Number(r.run_count)),
158
160
  maxTime: Number(r.max_time),
159
161
  }));
@@ -188,7 +190,7 @@ exports.default = (app) => {
188
190
  crons.forEach((c) => { nameMap[c.id] = c.name || c.command; });
189
191
  const data = rows.map((r, i) => ({
190
192
  rank: i + 1,
191
- name: nameMap[Number(r.ref_id)] || `任务#${r.ref_id}`,
193
+ name: nameMap[Number(r.ref_id)] || (0, i18n_1.tf)('任务#%s', r.ref_id),
192
194
  runCount: Number(r.run_count),
193
195
  avgTime: Math.round(Number(r.total_time) / Number(r.run_count)),
194
196
  successRate: Number(r.run_count) > 0
@@ -232,7 +234,7 @@ exports.default = (app) => {
232
234
  return {
233
235
  instanceId: inst.id,
234
236
  id: inst.cron_id,
235
- name: (cron === null || cron === void 0 ? void 0 : cron.name) || (cron === null || cron === void 0 ? void 0 : cron.command) || `任务#${inst.cron_id}`,
237
+ name: (cron === null || cron === void 0 ? void 0 : cron.name) || (cron === null || cron === void 0 ? void 0 : cron.command) || (0, i18n_1.tf)('任务#%s', inst.cron_id),
236
238
  pid: inst.pid,
237
239
  elapsed: inst.started_at ? now - inst.started_at : 0,
238
240
  logPath: inst.log_path,
@@ -257,7 +259,7 @@ exports.default = (app) => {
257
259
  running,
258
260
  idleTasks: idleTasks.map((c) => ({
259
261
  id: c.id,
260
- name: c.name || c.command || `任务#${c.id}`,
262
+ name: c.name || c.command || (0, i18n_1.tf)('任务#%s', c.id),
261
263
  lastRun: c.last_execution_time
262
264
  ? dayjs_1.default.unix(c.last_execution_time).format('MM-DD HH:mm')
263
265
  : '-',
@@ -283,7 +285,12 @@ exports.default = (app) => {
283
285
  let rawLabels = c.labels;
284
286
  if (typeof rawLabels === 'string')
285
287
  rawLabels = JSON.parse(rawLabels);
286
- const labels = Array.isArray(rawLabels) && rawLabels.length > 0 ? rawLabels : ['未分类'];
288
+ const labels = Array.isArray(rawLabels)
289
+ ? [...new Set(rawLabels.filter((l) => !(0, lodash_1.isEmpty)(l)))]
290
+ : [];
291
+ if (labels.length === 0) {
292
+ labels.push((0, i18n_1.t)('未分类'));
293
+ }
287
294
  const st = statMap[c.id];
288
295
  labels.forEach((label) => {
289
296
  if (!labelMap[label])
@@ -318,7 +325,7 @@ exports.default = (app) => {
318
325
  code: 200,
319
326
  data: {
320
327
  platform: os_1.default.platform(),
321
- uptime: Math.floor(os_1.default.uptime()),
328
+ uptime: Math.floor(process.uptime()),
322
329
  memTotal: os_1.default.totalmem(),
323
330
  memFree: os_1.default.freemem(),
324
331
  memUsagePercent: ((1 - os_1.default.freemem() / os_1.default.totalmem()) * 100).toFixed(1),
@@ -87,8 +87,6 @@ const extraFile = path_1.default.join(configPath, 'extra.sh');
87
87
  const confBakDir = path_1.default.join(dataPath, 'config/bak/');
88
88
  const sampleFile = path_1.default.join(samplePath, 'config.sample.sh');
89
89
  const sqliteFile = path_1.default.join(samplePath, 'database.sqlite');
90
- const authError = '错误的用户名密码,请重试';
91
- const loginFaild = '请先登录!';
92
90
  const configString = 'config sample crontab shareCode diy';
93
91
  const versionFile = path_1.default.join(rootPath, 'version.yaml');
94
92
  const dataTgzFile = path_1.default.join(tmpPath, 'data.tgz');
@@ -105,8 +103,6 @@ exports.default = Object.assign(Object.assign({}, config), { jwt: config.jwt, ba
105
103
  shareShellFile,
106
104
  dependenceProxyFile,
107
105
  configString,
108
- loginFaild,
109
- authError,
110
106
  logPath,
111
107
  extraFile,
112
108
  authConfigFile,
@@ -498,7 +498,7 @@ function safeJSONParse(value) {
498
498
  return JSON.parse(value);
499
499
  }
500
500
  catch (error) {
501
- logger_1.default.error('[safeJSONParse失败]', error);
501
+ logger_1.default.error('[safeJSONParse error]', error);
502
502
  return {};
503
503
  }
504
504
  }
@@ -511,7 +511,7 @@ async function rmPath(path) {
511
511
  }
512
512
  }
513
513
  catch (error) {
514
- logger_1.default.error('[rmPath失败]', error);
514
+ logger_1.default.error('[rmPath error]', error);
515
515
  }
516
516
  }
517
517
  exports.rmPath = rmPath;
@@ -525,7 +525,7 @@ async function setSystemTimezone(timezone) {
525
525
  return true;
526
526
  }
527
527
  catch (error) {
528
- logger_1.default.error('[setSystemTimezone失败]', error);
528
+ logger_1.default.error('[setSystemTimezone error]', error);
529
529
  return false;
530
530
  }
531
531
  }
@@ -6,6 +6,7 @@ class SockMessage {
6
6
  this.type = options.type;
7
7
  this.message = options.message;
8
8
  this.references = options.references;
9
+ this.status = options.status;
9
10
  }
10
11
  }
11
12
  exports.SockMessage = SockMessage;
@@ -11,6 +11,7 @@ const sshKey_1 = __importDefault(require("../services/sshKey"));
11
11
  const config_1 = __importDefault(require("../config"));
12
12
  const util_1 = require("../config/util");
13
13
  const path_1 = require("path");
14
+ const i18n_1 = require("../shared/i18n");
14
15
  exports.default = async () => {
15
16
  const systemService = typedi_1.Container.get(system_1.default);
16
17
  const scheduleService = typedi_1.Container.get(schedule_1.default);
@@ -24,7 +25,7 @@ exports.default = async () => {
24
25
  }
25
26
  const cron = {
26
27
  id: NaN,
27
- name: '生成token',
28
+ name: (0, i18n_1.t)('生成token'),
28
29
  command: tokenCommand,
29
30
  runOrigin: 'system',
30
31
  };
@@ -38,7 +39,7 @@ exports.default = async () => {
38
39
  if (data.info.logRemoveFrequency) {
39
40
  const rmlogCron = {
40
41
  id: data.id,
41
- name: '删除日志',
42
+ name: (0, i18n_1.t)('删除日志'),
42
43
  command: `ql rmlog ${data.info.logRemoveFrequency}`,
43
44
  runOrigin: 'system',
44
45
  };
@@ -588,21 +588,24 @@ let CronService = class CronService {
588
588
  async log(id) {
589
589
  const doc = await this.getDb({ id });
590
590
  if (!doc) {
591
- return '';
591
+ return { content: '', status: 'empty' };
592
592
  }
593
593
  if (doc.log_name === '/dev/null') {
594
- return '日志设置为忽略';
594
+ return { content: (0, i18n_1.t)('日志设置为忽略'), status: 'ignored' };
595
595
  }
596
596
  const absolutePath = path_1.default.resolve(config_1.default.logPath, `${doc.log_path}`);
597
597
  const logFileExist = doc.log_path && (await (0, util_1.fileExist)(absolutePath));
598
598
  if (logFileExist) {
599
- return await (0, util_1.getFileContentByName)(`${absolutePath}`);
599
+ const content = await (0, util_1.getFileContentByName)(`${absolutePath}`);
600
+ const isRunning = typeof doc.status === 'number' &&
601
+ [cron_1.CrontabStatus.running, cron_1.CrontabStatus.queued].includes(doc.status);
602
+ return { content, status: isRunning ? 'running' : 'completed' };
600
603
  }
601
604
  else {
602
605
  return typeof doc.status === 'number' &&
603
606
  [cron_1.CrontabStatus.queued, cron_1.CrontabStatus.running].includes(doc.status)
604
- ? '运行中...'
605
- : '日志不存在...';
607
+ ? { content: (0, i18n_1.t)('运行中...'), status: 'running' }
608
+ : { content: (0, i18n_1.t)('日志不存在...'), status: 'notFound' };
606
609
  }
607
610
  }
608
611
  async logs(id) {
@@ -38,6 +38,7 @@ const dayjs_1 = __importDefault(require("dayjs"));
38
38
  const pLimit_1 = __importDefault(require("../shared/pLimit"));
39
39
  const util_2 = require("../config/util");
40
40
  const const_1 = require("../config/const");
41
+ const i18n_1 = require("../shared/i18n");
41
42
  let DependenceService = class DependenceService {
42
43
  constructor(logger, sockService) {
43
44
  this.logger = logger;
@@ -183,7 +184,7 @@ let DependenceService = class DependenceService {
183
184
  }
184
185
  const depIds = [dependency.id];
185
186
  let depName = dependency.name.trim();
186
- const actionText = isInstall ? '安装' : '删除';
187
+ const actionText = isInstall ? (0, i18n_1.t)('安装') : (0, i18n_1.t)('删除');
187
188
  const socketMessageType = isInstall
188
189
  ? 'installDependence'
189
190
  : 'uninstallDependence';
@@ -197,11 +198,12 @@ let DependenceService = class DependenceService {
197
198
  if (!osType) {
198
199
  await dependence_1.DependenceModel.update({ status: dependence_1.DependenceStatus.installFailed }, { where: { id: depIds } });
199
200
  const startTime = (0, dayjs_1.default)();
200
- const message = `开始${actionText}依赖 ${depName},开始时间 ${startTime.format('YYYY-MM-DD HH:mm:ss')}\n\n当前系统不支持\n\n依赖${actionText}失败,结束时间 ${startTime.format('YYYY-MM-DD HH:mm:ss')},耗时 ${startTime.diff(startTime, 'second')} 秒`;
201
+ const message = (0, i18n_1.tf)('开始%s依赖 %s,开始时间 %s\n\n当前系统不支持\n\n依赖%s失败,结束时间 %s,耗时 %s 秒', actionText, depName, startTime.format('YYYY-MM-DD HH:mm:ss'), actionText, startTime.format('YYYY-MM-DD HH:mm:ss'), String(startTime.diff(startTime, 'second')));
201
202
  this.sockService.sendMessage({
202
203
  type: socketMessageType,
203
204
  message,
204
205
  references: depIds,
206
+ status: dependence_1.DependenceStatus.installFailed,
205
207
  });
206
208
  this.updateLog(depIds, message);
207
209
  return resolve(null);
@@ -221,11 +223,12 @@ let DependenceService = class DependenceService {
221
223
  : `${linuxCommand.uninstall} ${depName.trim()}`;
222
224
  }
223
225
  const startTime = (0, dayjs_1.default)();
224
- const message = `开始${actionText}依赖 ${depName},开始时间 ${startTime.format('YYYY-MM-DD HH:mm:ss')}\n\n`;
226
+ const message = (0, i18n_1.tf)('开始%s依赖 %s,开始时间 %s\n\n', actionText, depName, startTime.format('YYYY-MM-DD HH:mm:ss'));
225
227
  this.sockService.sendMessage({
226
228
  type: socketMessageType,
227
229
  message,
228
230
  references: depIds,
231
+ status,
229
232
  });
230
233
  this.updateLog(depIds, message);
231
234
  // 判断是否已经安装过依赖
@@ -254,11 +257,12 @@ let DependenceService = class DependenceService {
254
257
  isPythonDependence) &&
255
258
  (!depVersion || depInfo.includes(depVersion))) {
256
259
  const endTime = (0, dayjs_1.default)();
257
- const _message = `检测到已经安装 ${depName}\n\n${depInfo}\n\n跳过安装\n\n依赖${actionText}成功,结束时间 ${endTime.format('YYYY-MM-DD HH:mm:ss')},耗时 ${endTime.diff(startTime, 'second')} 秒`;
260
+ const _message = (0, i18n_1.tf)('检测到已经安装 %s\n\n%s\n\n跳过安装\n\n依赖%s成功,结束时间 %s,耗时 %s 秒', depName, depInfo, actionText, endTime.format('YYYY-MM-DD HH:mm:ss'), String(endTime.diff(startTime, 'second')));
258
261
  this.sockService.sendMessage({
259
262
  type: socketMessageType,
260
263
  message: _message,
261
264
  references: depIds,
265
+ status: dependence_1.DependenceStatus.installed,
262
266
  });
263
267
  this.updateLog(depIds, _message);
264
268
  await dependence_1.DependenceModel.update({ status: dependence_1.DependenceStatus.installed }, { where: { id: depIds } });
@@ -277,6 +281,7 @@ let DependenceService = class DependenceService {
277
281
  type: socketMessageType,
278
282
  message: data.toString(),
279
283
  references: depIds,
284
+ status,
280
285
  });
281
286
  this.updateLog(depIds, data.toString());
282
287
  });
@@ -285,6 +290,7 @@ let DependenceService = class DependenceService {
285
290
  type: socketMessageType,
286
291
  message: data.toString(),
287
292
  references: depIds,
293
+ status,
288
294
  });
289
295
  this.updateLog(depIds, data.toString());
290
296
  });
@@ -293,37 +299,32 @@ let DependenceService = class DependenceService {
293
299
  type: socketMessageType,
294
300
  message: JSON.stringify(err),
295
301
  references: depIds,
302
+ status,
296
303
  });
297
304
  this.updateLog(depIds, JSON.stringify(err));
298
305
  });
299
306
  cp.on('exit', async (code) => {
300
307
  const endTime = (0, dayjs_1.default)();
301
308
  const isSucceed = code === 0;
302
- const resultText = isSucceed ? '成功' : '失败';
303
- const message = `\n依赖${actionText}${resultText},结束时间 ${endTime.format('YYYY-MM-DD HH:mm:ss')},耗时 ${endTime.diff(startTime, 'second')} 秒`;
309
+ const resultText = isSucceed ? (0, i18n_1.t)('成功') : (0, i18n_1.t)('失败');
310
+ const message = '\n' +
311
+ (0, i18n_1.tf)('依赖%s%s,结束时间 %s,耗时 %s 秒', actionText, resultText, endTime.format('YYYY-MM-DD HH:mm:ss'), String(endTime.diff(startTime, 'second')));
312
+ const exitStatus = isSucceed
313
+ ? (isInstall ? dependence_1.DependenceStatus.installed : dependence_1.DependenceStatus.removed)
314
+ : (isInstall ? dependence_1.DependenceStatus.installFailed : dependence_1.DependenceStatus.removeFailed);
304
315
  this.sockService.sendMessage({
305
316
  type: socketMessageType,
306
317
  message,
307
318
  references: depIds,
319
+ status: exitStatus,
308
320
  });
309
321
  this.updateLog(depIds, message);
310
- let status;
311
- if (isSucceed) {
312
- status = isInstall
313
- ? dependence_1.DependenceStatus.installed
314
- : dependence_1.DependenceStatus.removed;
315
- }
316
- else {
317
- status = isInstall
318
- ? dependence_1.DependenceStatus.installFailed
319
- : dependence_1.DependenceStatus.removeFailed;
320
- }
321
322
  const docs = await dependence_1.DependenceModel.findAll({ where: { id: depIds } });
322
323
  const _docIds = docs
323
324
  .filter((x) => x.status !== dependence_1.DependenceStatus.cancelled)
324
325
  .map((x) => x.id);
325
326
  if (_docIds.length > 0) {
326
- await dependence_1.DependenceModel.update({ status }, { where: { id: _docIds } });
327
+ await dependence_1.DependenceModel.update({ status: exitStatus }, { where: { id: _docIds } });
327
328
  }
328
329
  // 如果删除依赖成功或者强制删除
329
330
  if ((isSucceed || force) && !isInstall) {
@@ -306,7 +306,7 @@ let NotificationService = class NotificationService {
306
306
  {
307
307
  title: `${this.title}`,
308
308
  thumb_media_id,
309
- author: `智能助手`,
309
+ author: (0, i18n_1.t)('智能助手'),
310
310
  content_source_url: ``,
311
311
  content: `${this.content.replace(/\n/g, '<br/>')}`,
312
312
  digest: `${this.content}`,
@@ -322,7 +322,7 @@ let NotificationService = class NotificationService {
322
322
  title: `${this.title}`,
323
323
  description: `${this.content}`,
324
324
  url: 'https://github.com/whyour/qinglong',
325
- btntxt: '更多',
325
+ btntxt: (0, i18n_1.t)('更多'),
326
326
  },
327
327
  };
328
328
  break;
@@ -361,7 +361,7 @@ let NotificationService = class NotificationService {
361
361
  roomName: `${aibotkName}`,
362
362
  message: {
363
363
  type: 1,
364
- content: `【青龙快讯】\n\n${this.title}\n${this.content}`,
364
+ content: `【${(0, i18n_1.t)('青龙快讯')}】\n\n${this.title}\n${this.content}`,
365
365
  },
366
366
  };
367
367
  break;
@@ -372,7 +372,7 @@ let NotificationService = class NotificationService {
372
372
  name: `${aibotkName}`,
373
373
  message: {
374
374
  type: 1,
375
- content: `【青龙快讯】\n\n${this.title}\n${this.content}`,
375
+ content: `【${(0, i18n_1.t)('青龙快讯')}】\n\n${this.title}\n${this.content}`,
376
376
  },
377
377
  };
378
378
  break;
@@ -507,7 +507,7 @@ let NotificationService = class NotificationService {
507
507
  },
508
508
  });
509
509
  const info = await transporter.sendMail({
510
- from: `"青龙快讯" <${emailUser}>`,
510
+ from: `"${(0, i18n_1.t)('青龙快讯')}" <${emailUser}>`,
511
511
  to: recipients,
512
512
  subject: `${this.title}`,
513
513
  html: `${this.content.replace(/\n/g, '<br/>')}`,
@@ -126,12 +126,12 @@ let SubscriptionService = class SubscriptionService {
126
126
  status: subscription_1.SubscriptionStatus.running,
127
127
  log_path: logPath,
128
128
  }, { where: { id: doc.id } });
129
- const absolutePath = await (0, util_1.handleLogPath)(logPath, `## 开始执行... ${startTime.format('YYYY-MM-DD HH:mm:ss')}\n`);
129
+ const absolutePath = await (0, util_1.handleLogPath)(logPath, (0, i18n_1.tf)('## 开始执行... %s\n', startTime.format('YYYY-MM-DD HH:mm:ss')));
130
130
  // 执行sub_before
131
131
  let beforeStr = '';
132
132
  try {
133
133
  if (doc.sub_before) {
134
- await logStreamManager_1.logStreamManager.write(absolutePath, `\n## 执行before命令...\n\n`);
134
+ await logStreamManager_1.logStreamManager.write(absolutePath, `\n## ${(0, i18n_1.t)('执行before命令...')}\n\n`);
135
135
  beforeStr = await (0, util_1.promiseExec)(doc.sub_before);
136
136
  }
137
137
  }
@@ -155,7 +155,7 @@ let SubscriptionService = class SubscriptionService {
155
155
  let afterStr = '';
156
156
  try {
157
157
  if (sub.sub_after) {
158
- await logStreamManager_1.logStreamManager.write(absolutePath, `\n\n## 执行after命令...\n\n`);
158
+ await logStreamManager_1.logStreamManager.write(absolutePath, `\n\n## ${(0, i18n_1.t)('执行after命令...')}\n\n`);
159
159
  afterStr = await (0, util_1.promiseExec)(sub.sub_after);
160
160
  }
161
161
  }
@@ -166,7 +166,9 @@ let SubscriptionService = class SubscriptionService {
166
166
  if (afterStr) {
167
167
  await logStreamManager_1.logStreamManager.write(absolutePath, `${afterStr}\n`);
168
168
  }
169
- await logStreamManager_1.logStreamManager.write(absolutePath, `\n## 执行结束... ${endTime.format('YYYY-MM-DD HH:mm:ss')} 耗时 ${diff} 秒${const_1.LOG_END_SYMBOL}`);
169
+ await logStreamManager_1.logStreamManager.write(absolutePath, '\n' +
170
+ (0, i18n_1.tf)('## 执行结束... %s 耗时 %s 秒', endTime.format('YYYY-MM-DD HH:mm:ss'), String(diff)) +
171
+ const_1.LOG_END_SYMBOL);
170
172
  // Close the stream after task completion
171
173
  await logStreamManager_1.logStreamManager.closeStream(absolutePath);
172
174
  await subscription_1.SubscriptionModel.update({ status: subscription_1.SubscriptionStatus.idle, pid: undefined }, { where: { id: sub.id } });
@@ -72,7 +72,7 @@ let SystemService = class SystemService {
72
72
  }
73
73
  async updateNotificationMode(notificationInfo) {
74
74
  const code = Math.random().toString().slice(-6);
75
- const isSuccess = await this.notificationService.testNotify(notificationInfo, '青龙', `【蛟龙】测试通知 https://t.me/jiao_long`);
75
+ const isSuccess = await this.notificationService.testNotify(notificationInfo, (0, i18n_1.t)('青龙'), (0, i18n_1.t)('【蛟龙】测试通知 https://t.me/jiao_long'));
76
76
  if (isSuccess) {
77
77
  const result = await this.updateAuthDb({
78
78
  type: system_1.AuthDataType.notification,
@@ -90,7 +90,7 @@ let SystemService = class SystemService {
90
90
  const result = await this.updateAuthDb(Object.assign(Object.assign({}, oDoc), { info: Object.assign(Object.assign({}, oDoc.info), info) }));
91
91
  const cron = {
92
92
  id: result.id,
93
- name: '删除日志',
93
+ name: (0, i18n_1.t)('删除日志'),
94
94
  command: `ql rmlog ${info.logRemoveFrequency}`,
95
95
  runOrigin: 'system',
96
96
  };
@@ -149,6 +149,7 @@ let SystemService = class SystemService {
149
149
  this.sockService.sendMessage({
150
150
  type: 'updateNodeMirror',
151
151
  message: 'update node mirror end',
152
+ status: 'completed',
152
153
  });
153
154
  },
154
155
  onError: async (message) => {
@@ -189,6 +190,7 @@ let SystemService = class SystemService {
189
190
  this.sockService.sendMessage({
190
191
  type: 'updateLinuxMirror',
191
192
  message: 'update linux mirror end',
193
+ status: 'completed',
192
194
  });
193
195
  onEnd === null || onEnd === void 0 ? void 0 : onEnd();
194
196
  if (!hasError) {
@@ -277,6 +279,14 @@ let SystemService = class SystemService {
277
279
  this.sockService.sendMessage({
278
280
  type: 'updateSystemVersion',
279
281
  message: JSON.stringify(err),
282
+ status: 'failed',
283
+ });
284
+ });
285
+ cp.on('exit', (code) => {
286
+ this.sockService.sendMessage({
287
+ type: 'updateSystemVersion',
288
+ message: '',
289
+ status: code === 0 ? 'success' : 'failed',
280
290
  });
281
291
  });
282
292
  return { code: 200 };
@@ -49,7 +49,7 @@ let UserService = class UserService {
49
49
  const waitTime = Math.ceil((retriesTime - (timestamp - lastlogon)) / 1000);
50
50
  return {
51
51
  code: 410,
52
- message: `失败次数过多,请${waitTime}秒后重试`,
52
+ message: (0, i18n_1.tf)('失败次数过多,请%s秒后重试', waitTime),
53
53
  data: waitTime,
54
54
  };
55
55
  }
@@ -98,7 +98,18 @@ let UserService = class UserService {
98
98
  platform: req.platform,
99
99
  isTwoFactorChecking: false,
100
100
  });
101
- this.notificationService.notify('登录通知', `你于${(0, dayjs_1.default)(timestamp).format('YYYY-MM-DD HH:mm:ss')}在 ${address} ${req.platform}端 登录成功,ip地址 ${ip}`);
101
+ this.notificationService.notify((0, i18n_1.t)('登录通知'), (0, i18n_1.t)('你于') +
102
+ (0, dayjs_1.default)(timestamp).format('YYYY-MM-DD HH:mm:ss') +
103
+ (0, i18n_1.t)('在') +
104
+ address +
105
+ ' ' +
106
+ req.platform +
107
+ (0, i18n_1.t)('端') +
108
+ ' ' +
109
+ (0, i18n_1.t)('登录成功') +
110
+ (0, i18n_1.t)(',ip地址') +
111
+ ' ' +
112
+ ip);
102
113
  await this.insertDb({
103
114
  type: system_1.AuthDataType.loginLog,
104
115
  info: {
@@ -130,7 +141,18 @@ let UserService = class UserService {
130
141
  lastaddr: address,
131
142
  platform: req.platform,
132
143
  });
133
- this.notificationService.notify('登录通知', `你于${(0, dayjs_1.default)(timestamp).format('YYYY-MM-DD HH:mm:ss')}在 ${address} ${req.platform}端 登录失败,ip地址 ${ip}`);
144
+ this.notificationService.notify((0, i18n_1.t)('登录通知'), (0, i18n_1.t)('你于') +
145
+ (0, dayjs_1.default)(timestamp).format('YYYY-MM-DD HH:mm:ss') +
146
+ (0, i18n_1.t)('在') +
147
+ address +
148
+ ' ' +
149
+ req.platform +
150
+ (0, i18n_1.t)('端') +
151
+ ' ' +
152
+ (0, i18n_1.t)('登录失败') +
153
+ (0, i18n_1.t)(',ip地址') +
154
+ ' ' +
155
+ ip);
134
156
  await this.insertDb({
135
157
  type: system_1.AuthDataType.loginLog,
136
158
  info: {
@@ -146,12 +168,12 @@ let UserService = class UserService {
146
168
  const waitTime = Math.round(Math.pow(3, retries + 1));
147
169
  return {
148
170
  code: 410,
149
- message: `失败次数过多,请${waitTime}秒后重试`,
171
+ message: (0, i18n_1.tf)('失败次数过多,请%s秒后重试', waitTime),
150
172
  data: waitTime,
151
173
  };
152
174
  }
153
175
  else {
154
- return { code: 400, message: config_1.default.authError };
176
+ return { code: 400, message: (0, i18n_1.t)('错误的用户名密码,请重试') };
155
177
  }
156
178
  }
157
179
  }
@@ -308,7 +330,7 @@ let UserService = class UserService {
308
330
  }
309
331
  async updateNotificationMode(notificationInfo) {
310
332
  const code = Math.random().toString().slice(-6);
311
- const isSuccess = await this.notificationService.testNotify(notificationInfo, '青龙', `【蛟龙】测试通知 https://t.me/jiao_long`);
333
+ const isSuccess = await this.notificationService.testNotify(notificationInfo, (0, i18n_1.t)('青龙'), (0, i18n_1.t)('【蛟龙】测试通知 https://t.me/jiao_long'));
312
334
  if (isSuccess) {
313
335
  const result = await this.updateAuthDb({
314
336
  type: system_1.AuthDataType.notification,
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.t = exports.getLang = exports.setLang = void 0;
3
+ exports.tf = exports.t = exports.getLang = exports.setLang = void 0;
4
4
  const messages = {
5
5
  zh: {},
6
6
  en: {
@@ -83,6 +83,46 @@ const messages = {
83
83
  '订阅执行完成': 'Subscription completed',
84
84
  'wxPusher 服务的 TopicIds 和 Uids 至少配置一个才行': 'wxPusher requires at least one of TopicIds or Uids',
85
85
  'Url 或者 Body 中必须包含 $title': 'Url or Body must contain $title',
86
+ '绝对路径必须在日志目录内或使用 /dev/null': 'Absolute path must be within log directory or use /dev/null',
87
+ '请先登录!': 'Please login first!',
88
+ '运行中...': 'Running...',
89
+ '日志不存在...': 'Log does not exist...',
90
+ '未分类': 'Uncategorized',
91
+ '任务重复运行': 'Duplicate task execution',
92
+ '日志设置为忽略': 'Log set to ignore',
93
+ '定时规则不能为空': 'Schedule rule cannot be empty',
94
+ '无效的定时规则': 'Invalid schedule rule',
95
+ '日志名称只能包含字母、数字、下划线和连字符': 'Log name can only contain letters, numbers, underscores, and hyphens',
96
+ '日志名称不能超过100个字符': 'Log name cannot exceed 100 characters',
97
+ '错误的用户名密码,请重试': 'Incorrect username or password, please try again',
98
+ '青龙快讯': 'QingLong',
99
+ '登录通知': 'Login Notification',
100
+ '你于': 'You at ',
101
+ '在': ' in ',
102
+ 端: '',
103
+ 登录失败: 'login failed',
104
+ ',ip地址': ', IP: ',
105
+ '任务#%s': 'Task#%s',
106
+ 安装: 'Install',
107
+ 删除: 'Uninstall',
108
+ 成功: 'Succeeded',
109
+ 失败: 'Failed',
110
+ '失败次数过多,请%s秒后重试': 'Too many failed attempts, please retry in %s seconds',
111
+ 智能助手: 'Smart Assistant',
112
+ 更多: 'More',
113
+ '开始%s依赖 %s,开始时间 %s\n\n当前系统不支持\n\n依赖%s失败,结束时间 %s,耗时 %s 秒': 'Start %s dependency %s, start time %s\n\nCurrent system not supported\n\nDependency %s failed, end time %s, elapsed %s seconds',
114
+ '检测到已经安装 %s\n\n%s\n\n跳过安装\n\n依赖%s成功,结束时间 %s,耗时 %s 秒': 'Already installed %s\n\n%s\n\nSkipping install\n\nDependency %s succeeded, end time %s, elapsed %s seconds',
115
+ '开始%s依赖 %s,开始时间 %s\n\n': 'Start %s dependency %s, start time %s\n\n',
116
+ '依赖%s%s,结束时间 %s,耗时 %s 秒': 'Dependency %s%s, end time %s, elapsed %s seconds',
117
+ '任务:%s,命令:%s,定时:%s,处于运行中的超过 %d 个,请检查定时设置': 'Task: %s, command: %s, schedule: %s, more than %d instances running, please check schedule settings',
118
+ 青龙: 'QingLong',
119
+ '【蛟龙】测试通知 https://t.me/jiao_long': '[JiaoLong] Test notification https://t.me/jiao_long',
120
+ '生成token': 'Generate token',
121
+ '删除日志': 'Delete logs',
122
+ '## 开始执行... %s\n': '## Start executing... %s\n',
123
+ '执行before命令...': 'Execute before command...',
124
+ '执行after命令...': 'Execute after command...',
125
+ '## 执行结束... %s 耗时 %s 秒': '## Execution finished... %s elapsed %s seconds',
86
126
  },
87
127
  };
88
128
  let currentLang = 'zh';
@@ -102,4 +142,8 @@ function t(key, lang) {
102
142
  return key;
103
143
  }
104
144
  exports.t = t;
145
+ function tf(key, ...args) {
146
+ return args.reduce((str, arg) => str.replace(/%s|%d/, String(arg)), t(key));
147
+ }
148
+ exports.tf = tf;
105
149
  //# sourceMappingURL=i18n.js.map
@@ -8,6 +8,7 @@ const os_1 = __importDefault(require("os"));
8
8
  const system_1 = require("../data/system");
9
9
  const logger_1 = __importDefault(require("../loaders/logger"));
10
10
  const notify_1 = __importDefault(require("../services/notify"));
11
+ const i18n_1 = require("../shared/i18n");
11
12
  const config_1 = __importDefault(require("../config"));
12
13
  const grpc_js_1 = require("@grpc/grpc-js");
13
14
  const api_1 = require("../protos/api");
@@ -117,8 +118,8 @@ class TaskLimit {
117
118
  if (repeatTimes < 3) {
118
119
  this.repeatCronNotifyMap.set(cron.id, repeatTimes + 1);
119
120
  this.client.systemNotify({
120
- title: '任务重复运行',
121
- content: `任务:${cron.name},命令:${cron.command},定时:${cron.schedule},处于运行中的超过 5 个,请检查定时设置`,
121
+ title: (0, i18n_1.t)('任务重复运行'),
122
+ content: (0, i18n_1.tf)('任务:%s,命令:%s,定时:%s,处于运行中的超过 %d 个,请检查定时设置', cron.name || '', cron.command || '', cron.schedule || '', 5),
122
123
  }, (err, res) => {
123
124
  if (err) {
124
125
  logger_1.default.error(`[schedule][任务重复运行] 通知失败 ${JSON.stringify(err)}`);