修复国际化文案

This commit is contained in:
whyour
2026-06-21 23:53:32 +08:00
parent 369dd13212
commit 3044f63f03
28 changed files with 335 additions and 187 deletions
+10 -6
View File
@@ -712,23 +712,27 @@ export default class CronService {
await this.setCrontab();
}
public async log(id: number) {
public async log(id: number): Promise<{ content: string; status: string }> {
const doc = await this.getDb({ id });
if (!doc) {
return '';
return { content: '', status: 'empty' };
}
if (doc.log_name === '/dev/null') {
return '日志设置为忽略';
return { content: t('日志设置为忽略'), status: 'ignored' };
}
const absolutePath = path.resolve(config.logPath, `${doc.log_path}`);
const logFileExist = doc.log_path && (await fileExist(absolutePath));
if (logFileExist) {
return await getFileContentByName(`${absolutePath}`);
const content = await getFileContentByName(`${absolutePath}`);
const isRunning =
typeof doc.status === 'number' &&
[CrontabStatus.running, CrontabStatus.queued].includes(doc.status);
return { content, status: isRunning ? 'running' : 'completed' };
} else {
return typeof doc.status === 'number' &&
[CrontabStatus.queued, CrontabStatus.running].includes(doc.status)
? '运行中...'
: '日志不存在...';
? { content: t('运行中...'), status: 'running' }
: { content: t('日志不存在...'), status: 'notFound' };
}
}
+45 -27
View File
@@ -24,6 +24,7 @@ import dayjs from 'dayjs';
import taskLimit from '../shared/pLimit';
import { detectOS } from '../config/util';
import { LINUX_DEPENDENCE_COMMAND } from '../config/const';
import { t, tf } from '../shared/i18n';
@Service()
export default class DependenceService {
@@ -232,7 +233,7 @@ export default class DependenceService {
}
const depIds = [dependency.id!];
let depName = dependency.name.trim();
const actionText = isInstall ? '安装' : '删除';
const actionText = isInstall ? t('安装') : t('删除');
const socketMessageType = isInstall
? 'installDependence'
: 'uninstallDependence';
@@ -249,15 +250,20 @@ export default class DependenceService {
{ where: { id: depIds } },
);
const startTime = dayjs();
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')}`;
const message = 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')),
);
this.sockService.sendMessage({
type: socketMessageType,
message,
references: depIds,
status: DependenceStatus.installFailed,
});
this.updateLog(depIds, message);
return resolve(null);
@@ -280,13 +286,17 @@ export default class DependenceService {
}
const startTime = dayjs();
const message = `开始${actionText}依赖 ${depName},开始时间 ${startTime.format(
'YYYY-MM-DD HH:mm:ss',
)}\n\n`;
const message = tf(
'开始%s依赖 %s,开始时间 %s\n\n',
actionText,
depName,
startTime.format('YYYY-MM-DD HH:mm:ss'),
);
this.sockService.sendMessage({
type: socketMessageType,
message,
references: depIds,
status,
});
this.updateLog(depIds, message);
@@ -322,13 +332,19 @@ export default class DependenceService {
(!depVersion || depInfo.includes(depVersion))
) {
const endTime = dayjs();
const _message = `检测到已经安装 ${depName}\n\n${depInfo}\n\n跳过安装\n\n依赖${actionText}成功,结束时间 ${endTime.format(
'YYYY-MM-DD HH:mm:ss',
)},耗时 ${endTime.diff(startTime, 'second')}`;
const _message = 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')),
);
this.sockService.sendMessage({
type: socketMessageType,
message: _message,
references: depIds,
status: DependenceStatus.installed,
});
this.updateLog(depIds, _message);
await DependenceModel.update(
@@ -353,6 +369,7 @@ export default class DependenceService {
type: socketMessageType,
message: data.toString(),
references: depIds,
status,
});
this.updateLog(depIds, data.toString());
});
@@ -362,6 +379,7 @@ export default class DependenceService {
type: socketMessageType,
message: data.toString(),
references: depIds,
status,
});
this.updateLog(depIds, data.toString());
});
@@ -371,6 +389,7 @@ export default class DependenceService {
type: socketMessageType,
message: JSON.stringify(err),
references: depIds,
status,
});
this.updateLog(depIds, JSON.stringify(err));
});
@@ -378,28 +397,27 @@ export default class DependenceService {
cp.on('exit', async (code) => {
const endTime = dayjs();
const isSucceed = code === 0;
const resultText = isSucceed ? '成功' : '失败';
const resultText = isSucceed ? t('成功') : t('失败');
const message = `\n依赖${actionText}${resultText},结束时间 ${endTime.format(
'YYYY-MM-DD HH:mm:ss',
)},耗时 ${endTime.diff(startTime, 'second')}`;
const message =
'\n' +
tf('依赖%s%s,结束时间 %s,耗时 %s 秒',
actionText,
resultText,
endTime.format('YYYY-MM-DD HH:mm:ss'),
String(endTime.diff(startTime, 'second')),
);
const exitStatus = isSucceed
? (isInstall ? DependenceStatus.installed : DependenceStatus.removed)
: (isInstall ? DependenceStatus.installFailed : DependenceStatus.removeFailed);
this.sockService.sendMessage({
type: socketMessageType,
message,
references: depIds,
status: exitStatus,
});
this.updateLog(depIds, message);
let status: number;
if (isSucceed) {
status = isInstall
? DependenceStatus.installed
: DependenceStatus.removed;
} else {
status = isInstall
? DependenceStatus.installFailed
: DependenceStatus.removeFailed;
}
const docs = await DependenceModel.findAll({ where: { id: depIds } });
const _docIds = docs
.filter((x) => x.status !== DependenceStatus.cancelled)
@@ -407,7 +425,7 @@ export default class DependenceService {
if (_docIds.length > 0) {
await DependenceModel.update(
{ status },
{ status: exitStatus },
{ where: { id: _docIds } },
);
}
+5 -5
View File
@@ -365,7 +365,7 @@ export default class NotificationService {
{
title: `${this.title}`,
thumb_media_id,
author: `智能助手`,
author: t('智能助手'),
content_source_url: ``,
content: `${this.content.replace(/\n/g, '<br/>')}`,
digest: `${this.content}`,
@@ -381,7 +381,7 @@ export default class NotificationService {
title: `${this.title}`,
description: `${this.content}`,
url: 'https://github.com/whyour/qinglong',
btntxt: '更多',
btntxt: t('更多'),
},
};
break;
@@ -432,7 +432,7 @@ export default class NotificationService {
roomName: `${aibotkName}`,
message: {
type: 1,
content: `青龙快讯\n\n${this.title}\n${this.content}`,
content: `${t('青龙快讯')}\n\n${this.title}\n${this.content}`,
},
};
break;
@@ -443,7 +443,7 @@ export default class NotificationService {
name: `${aibotkName}`,
message: {
type: 1,
content: `青龙快讯\n\n${this.title}\n${this.content}`,
content: `${t('青龙快讯')}\n\n${this.title}\n${this.content}`,
},
};
break;
@@ -613,7 +613,7 @@ export default class NotificationService {
});
const info = await transporter.sendMail({
from: `"青龙快讯" <${emailUser}>`,
from: `"${t('青龙快讯')}" <${emailUser}>`,
to: recipients,
subject: `${this.title}`,
html: `${this.content.replace(/\n/g, '<br/>')}`,
+11 -7
View File
@@ -24,7 +24,7 @@ import path, { join } from 'path';
import ScheduleService, { TaskCallbacks } from './schedule';
import { SimpleIntervalSchedule } from 'toad-scheduler';
import SockService from './sock';
import { t } from '../shared/i18n';
import { t, tf } from '../shared/i18n';
import SshKeyService from './sshKey';
import dayjs from 'dayjs';
import { LOG_END_SYMBOL } from '../config/const';
@@ -131,14 +131,14 @@ export default class SubscriptionService {
);
const absolutePath = await handleLogPath(
logPath as string,
`## 开始执行... ${startTime.format('YYYY-MM-DD HH:mm:ss')}\n`,
tf('## 开始执行... %s\n', startTime.format('YYYY-MM-DD HH:mm:ss')),
);
// 执行sub_before
let beforeStr = '';
try {
if (doc.sub_before) {
await logStreamManager.write(absolutePath, `\n## 执行before命令...\n\n`);
await logStreamManager.write(absolutePath, `\n## ${t('执行before命令...')}\n\n`);
beforeStr = await promiseExec(doc.sub_before);
}
} catch (error: any) {
@@ -165,7 +165,7 @@ export default class SubscriptionService {
let afterStr = '';
try {
if (sub.sub_after) {
await logStreamManager.write(absolutePath, `\n\n## 执行after命令...\n\n`);
await logStreamManager.write(absolutePath, `\n\n## ${t('执行after命令...')}\n\n`);
afterStr = await promiseExec(sub.sub_after);
}
} catch (error: any) {
@@ -178,9 +178,13 @@ export default class SubscriptionService {
await logStreamManager.write(
absolutePath,
`\n## 执行结束... ${endTime.format(
'YYYY-MM-DD HH:mm:ss',
)} 耗时 ${diff}${LOG_END_SYMBOL}`,
'\n' +
tf(
'## 执行结束... %s 耗时 %s 秒',
endTime.format('YYYY-MM-DD HH:mm:ss'),
String(diff),
) +
LOG_END_SYMBOL,
);
// Close the stream after task completion
+14 -3
View File
@@ -78,8 +78,8 @@ export default class SystemService {
const code = Math.random().toString().slice(-6);
const isSuccess = await this.notificationService.testNotify(
notificationInfo,
'青龙',
`【蛟龙】测试通知 https://t.me/jiao_long`,
t('青龙'),
t('【蛟龙】测试通知 https://t.me/jiao_long'),
);
if (isSuccess) {
const result = await this.updateAuthDb({
@@ -100,7 +100,7 @@ export default class SystemService {
});
const cron = {
id: result.id as number,
name: '删除日志',
name: t('删除日志'),
command: `ql rmlog ${info.logRemoveFrequency}`,
runOrigin: 'system' as const,
};
@@ -179,6 +179,7 @@ export default class SystemService {
this.sockService.sendMessage({
type: 'updateNodeMirror',
message: 'update node mirror end',
status: 'completed',
});
},
onError: async (message: string) => {
@@ -232,6 +233,7 @@ export default class SystemService {
this.sockService.sendMessage({
type: 'updateLinuxMirror',
message: 'update linux mirror end',
status: 'completed',
});
onEnd?.();
if (!hasError) {
@@ -340,6 +342,15 @@ export default class SystemService {
this.sockService.sendMessage({
type: 'updateSystemVersion',
message: JSON.stringify(err),
status: 'failed',
});
});
cp.on('exit', (code) => {
this.sockService.sendMessage({
type: 'updateSystemVersion',
message: '',
status: code === 0 ? 'success' : 'failed',
});
});
+32 -14
View File
@@ -25,7 +25,7 @@ import uniq from 'lodash/uniq';
import pickBy from 'lodash/pickBy';
import isNil from 'lodash/isNil';
import { shareStore } from '../shared/store';
import { t } from '../shared/i18n';
import { t, tf } from '../shared/i18n';
@Service()
export default class UserService {
@@ -67,7 +67,7 @@ export default class UserService {
);
return {
code: 410,
message: `失败次数过多,请${waitTime}秒后重试`,
message: tf('失败次数过多,请%s秒后重试', waitTime),
data: waitTime,
};
}
@@ -128,10 +128,19 @@ export default class UserService {
isTwoFactorChecking: false,
});
this.notificationService.notify(
'登录通知',
`你于${dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss')}${address} ${
req.platform
}端 登录成功,ip地址 ${ip}`,
t('登录通知'),
t('你于') +
dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss') +
t('在') +
address +
' ' +
req.platform +
t('端') +
' ' +
t('登录成功') +
t('ip地址') +
' ' +
ip,
);
await this.insertDb({
type: AuthDataType.loginLog,
@@ -164,10 +173,19 @@ export default class UserService {
platform: req.platform,
});
this.notificationService.notify(
'登录通知',
`你于${dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss')}${address} ${
req.platform
}端 登录失败,ip地址 ${ip}`,
t('登录通知'),
t('你于') +
dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss') +
t('在') +
address +
' ' +
req.platform +
t('端') +
' ' +
t('登录失败') +
t('ip地址') +
' ' +
ip,
);
await this.insertDb({
type: AuthDataType.loginLog,
@@ -184,11 +202,11 @@ export default class UserService {
const waitTime = Math.round(Math.pow(3, retries + 1));
return {
code: 410,
message: `失败次数过多,请${waitTime}秒后重试`,
message: tf('失败次数过多,请%s秒后重试', waitTime),
data: waitTime,
};
} else {
return { code: 400, message: config.authError };
return { code: 400, message: t('错误的用户名密码,请重试') };
}
}
}
@@ -389,8 +407,8 @@ export default class UserService {
const code = Math.random().toString().slice(-6);
const isSuccess = await this.notificationService.testNotify(
notificationInfo,
'青龙',
`【蛟龙】测试通知 https://t.me/jiao_long`,
t('青龙'),
t('【蛟龙】测试通知 https://t.me/jiao_long'),
);
if (isSuccess) {
const result = await this.updateAuthDb({