daodou-command 1.3.0 → 1.4.0
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.
- package/.daodourc.example +85 -0
- package/.idea/UniappTool.xml +10 -0
- package/.idea/copilot.data.migration.agent.xml +6 -0
- package/.idea/copilot.data.migration.ask.xml +6 -0
- package/.idea/copilot.data.migration.ask2agent.xml +6 -0
- package/.idea/copilot.data.migration.edit.xml +6 -0
- package/.idea/daodou-command.iml +12 -0
- package/.idea/editorJumperProjectSettings.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/workspace.xml +85 -0
- package/CHANGELOG.md +15 -3
- package/README.md +45 -2
- package/lib/commands/config.js +57 -3
- package/lib/commands/lang.js +2 -1
- package/lib/translation/TranslationService.js +214 -0
- package/lib/translation/engines/BaseTranslator.js +90 -0
- package/lib/translation/engines/ali/AliTranslator.js +316 -0
- package/lib/translation/engines/ali/index.js +8 -0
- package/lib/translation/engines/baidu/BaiduTranslator.js +209 -0
- package/lib/translation/engines/baidu/index.js +8 -0
- package/lib/translation/engines/deepl/DeeplTranslator.js +234 -0
- package/lib/translation/engines/deepl/index.js +8 -0
- package/lib/translation/engines/google/GoogleTranslator.js +251 -0
- package/lib/translation/engines/google/index.js +8 -0
- package/lib/translation/engines/index.js +69 -0
- package/lib/translation/engines/microsoft/MicrosoftTranslator.js +190 -0
- package/lib/translation/engines/microsoft/index.js +6 -0
- package/lib/translation/engines/microsoft/services/EdgeAuthService.js +166 -0
- package/lib/translation/engines/microsoft/services/HttpClient.js +93 -0
- package/lib/translation/engines/microsoft/services/TranslatorService.js +167 -0
- package/lib/translation/engines/microsoft/types/index.js +147 -0
- package/lib/translation/engines/openai/OpenaiTranslator.js +363 -0
- package/lib/translation/engines/openai/index.js +8 -0
- package/lib/translation/engines/youdao/YoudaoTranslator.js +361 -0
- package/lib/translation/engines/youdao/index.js +8 -0
- package/lib/translation/index.js +10 -0
- package/lib/utils/config.js +99 -2
- package/lib/utils/translation.js +58 -100
- package/package.json +1 -3
- package/.daodourc +0 -25
- package/lib/utils/proxy-manager.js +0 -364
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 有道翻译引擎实现
|
|
3
|
+
* 基于有道翻译API的付费翻译服务
|
|
4
|
+
*/
|
|
5
|
+
const BaseTranslator = require('../BaseTranslator');
|
|
6
|
+
const axios = require('axios');
|
|
7
|
+
const crypto = require('crypto');
|
|
8
|
+
|
|
9
|
+
class YoudaoTranslator extends BaseTranslator {
|
|
10
|
+
constructor(config = {}) {
|
|
11
|
+
super(config);
|
|
12
|
+
this.name = 'Youdao Translator';
|
|
13
|
+
this.priority = 5;
|
|
14
|
+
this.intervalLimit = 1000; // 1秒间隔限制
|
|
15
|
+
this.contentLengthLimit = 2000; // 2KB内容长度限制
|
|
16
|
+
|
|
17
|
+
// 有道翻译API配置
|
|
18
|
+
this.baseUrl = 'https://openapi.youdao.com/api';
|
|
19
|
+
this.appId = config.appId || '';
|
|
20
|
+
this.appKey = config.appKey || '';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 获取翻译器名称
|
|
25
|
+
*/
|
|
26
|
+
getName() {
|
|
27
|
+
return this.name;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 获取优先级
|
|
32
|
+
*/
|
|
33
|
+
getPriority() {
|
|
34
|
+
return this.priority;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 检查翻译器是否可用
|
|
39
|
+
*/
|
|
40
|
+
async isAvailable() {
|
|
41
|
+
if (!this.appId || !this.appKey) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
// 尝试翻译一个简单的测试文本
|
|
47
|
+
const testResult = await this.translate('hello', 'en', 'zh');
|
|
48
|
+
return testResult && testResult.success;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 翻译文本
|
|
56
|
+
*/
|
|
57
|
+
async translate(text, sourceLang, targetLang, options = {}) {
|
|
58
|
+
if (!text || !targetLang) {
|
|
59
|
+
throw new Error('文本和目标语言不能为空');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!this.appId || !this.appKey) {
|
|
63
|
+
throw new Error('有道翻译需要配置App ID和App Key');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return await this.withRetry(async () => {
|
|
67
|
+
try {
|
|
68
|
+
// 语言代码转换
|
|
69
|
+
const youdaoSourceLang = this.convertLangCode(sourceLang);
|
|
70
|
+
const youdaoTargetLang = this.convertLangCode(targetLang);
|
|
71
|
+
|
|
72
|
+
// 生成签名
|
|
73
|
+
const salt = Date.now().toString();
|
|
74
|
+
const curtime = Math.round(Date.now() / 1000).toString();
|
|
75
|
+
const signStr = this.appId + this.truncate(text) + salt + curtime + this.appKey;
|
|
76
|
+
const sign = crypto.createHash('sha256').update(signStr).digest('hex');
|
|
77
|
+
|
|
78
|
+
// 构建请求参数
|
|
79
|
+
const params = {
|
|
80
|
+
q: text,
|
|
81
|
+
from: youdaoSourceLang,
|
|
82
|
+
to: youdaoTargetLang,
|
|
83
|
+
appKey: this.appId,
|
|
84
|
+
salt: salt,
|
|
85
|
+
sign: sign,
|
|
86
|
+
signType: 'v3',
|
|
87
|
+
curtime: curtime
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// 发送请求
|
|
91
|
+
const response = await axios.post(this.baseUrl, params, {
|
|
92
|
+
headers: {
|
|
93
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
94
|
+
},
|
|
95
|
+
timeout: 10000
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (!response.data) {
|
|
99
|
+
throw new Error('有道翻译返回数据为空');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const result = response.data;
|
|
103
|
+
|
|
104
|
+
// 检查错误码
|
|
105
|
+
if (result.errorCode && result.errorCode !== '0') {
|
|
106
|
+
const errorMsg = this.getErrorMessage(result.errorCode);
|
|
107
|
+
throw new Error(`有道翻译错误 (${result.errorCode}): ${errorMsg}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!result.translation || !Array.isArray(result.translation)) {
|
|
111
|
+
throw new Error('有道翻译结果格式错误');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const translation = result.translation[0];
|
|
115
|
+
if (!translation) {
|
|
116
|
+
throw new Error('有道翻译结果为空');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
text: translation || text,
|
|
121
|
+
sourceLang: sourceLang,
|
|
122
|
+
targetLang: targetLang,
|
|
123
|
+
engine: this.name,
|
|
124
|
+
success: true,
|
|
125
|
+
confidence: 1.0,
|
|
126
|
+
alternatives: []
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (error.response) {
|
|
131
|
+
const status = error.response.status;
|
|
132
|
+
if (status === 429) {
|
|
133
|
+
throw new Error('有道翻译请求过于频繁,请稍后重试');
|
|
134
|
+
} else if (status === 403) {
|
|
135
|
+
throw new Error('有道翻译API密钥无效');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
throw new Error(`有道翻译失败: ${error.message}`);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* 截断文本(有道API要求)
|
|
145
|
+
*/
|
|
146
|
+
truncate(text) {
|
|
147
|
+
if (text.length <= 20) {
|
|
148
|
+
return text;
|
|
149
|
+
}
|
|
150
|
+
return text.substring(0, 10) + text.length + text.substring(text.length - 10);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* 获取支持的语言列表
|
|
155
|
+
*/
|
|
156
|
+
async getSupportedLanguages() {
|
|
157
|
+
// 有道支持的语言列表
|
|
158
|
+
return [
|
|
159
|
+
'auto', 'zh-CHS', 'zh-CHT', 'en', 'ja', 'ko', 'fr', 'es', 'pt', 'it', 'ru', 'vi', 'de', 'ar', 'id', 'af',
|
|
160
|
+
'bs', 'bg', 'ca', 'cs', 'cy', 'da', 'el', 'et', 'fa', 'fi', 'fr', 'gl', 'gu', 'he', 'hi', 'hr', 'ht', 'hu',
|
|
161
|
+
'is', 'ja', 'ko', 'lt', 'lv', 'ms', 'mt', 'mww', 'nl', 'no', 'pl', 'pt', 'ro', 'ru', 'sk', 'sl', 'sr', 'sv',
|
|
162
|
+
'sw', 'th', 'tr', 'uk', 'ur', 'vi', 'zh-CHS', 'zh-CHT'
|
|
163
|
+
];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* 语言代码转换
|
|
168
|
+
* 将标准语言代码转换为有道翻译支持的语言代码
|
|
169
|
+
*/
|
|
170
|
+
convertLangCode(langCode) {
|
|
171
|
+
const langMap = {
|
|
172
|
+
'zh': 'zh-CHS',
|
|
173
|
+
'zh-CN': 'zh-CHS',
|
|
174
|
+
'zh-TW': 'zh-CHT',
|
|
175
|
+
'en': 'en',
|
|
176
|
+
'ja': 'ja',
|
|
177
|
+
'ko': 'ko',
|
|
178
|
+
'fr': 'fr',
|
|
179
|
+
'es': 'es',
|
|
180
|
+
'pt': 'pt',
|
|
181
|
+
'it': 'it',
|
|
182
|
+
'ru': 'ru',
|
|
183
|
+
'vi': 'vi',
|
|
184
|
+
'de': 'de',
|
|
185
|
+
'ar': 'ar',
|
|
186
|
+
'id': 'id',
|
|
187
|
+
'af': 'af',
|
|
188
|
+
'bs': 'bs',
|
|
189
|
+
'bg': 'bg',
|
|
190
|
+
'ca': 'ca',
|
|
191
|
+
'cs': 'cs',
|
|
192
|
+
'cy': 'cy',
|
|
193
|
+
'da': 'da',
|
|
194
|
+
'el': 'el',
|
|
195
|
+
'et': 'et',
|
|
196
|
+
'fa': 'fa',
|
|
197
|
+
'fi': 'fi',
|
|
198
|
+
'gl': 'gl',
|
|
199
|
+
'gu': 'gu',
|
|
200
|
+
'he': 'he',
|
|
201
|
+
'hi': 'hi',
|
|
202
|
+
'hr': 'hr',
|
|
203
|
+
'ht': 'ht',
|
|
204
|
+
'hu': 'hu',
|
|
205
|
+
'is': 'is',
|
|
206
|
+
'lt': 'lt',
|
|
207
|
+
'lv': 'lv',
|
|
208
|
+
'ms': 'ms',
|
|
209
|
+
'mt': 'mt',
|
|
210
|
+
'mww': 'mww',
|
|
211
|
+
'nl': 'nl',
|
|
212
|
+
'no': 'no',
|
|
213
|
+
'pl': 'pl',
|
|
214
|
+
'ro': 'ro',
|
|
215
|
+
'sk': 'sk',
|
|
216
|
+
'sl': 'sl',
|
|
217
|
+
'sr': 'sr',
|
|
218
|
+
'sv': 'sv',
|
|
219
|
+
'sw': 'sw',
|
|
220
|
+
'th': 'th',
|
|
221
|
+
'tr': 'tr',
|
|
222
|
+
'uk': 'uk',
|
|
223
|
+
'ur': 'ur',
|
|
224
|
+
'auto': 'auto'
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
return langMap[langCode] || langCode.toLowerCase();
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* 获取错误信息
|
|
232
|
+
*/
|
|
233
|
+
getErrorMessage(errorCode) {
|
|
234
|
+
const errorMessages = {
|
|
235
|
+
'101': '缺少必填的参数',
|
|
236
|
+
'102': '不支持的语言类型',
|
|
237
|
+
'103': '翻译文本过长',
|
|
238
|
+
'104': '不支持的API类型',
|
|
239
|
+
'105': '不支持的签名类型',
|
|
240
|
+
'106': '不支持的响应类型',
|
|
241
|
+
'107': '不支持的传输协议',
|
|
242
|
+
'108': 'appKey无效',
|
|
243
|
+
'109': 'batchLog格式不正确',
|
|
244
|
+
'110': '无相关服务的有效实例',
|
|
245
|
+
'111': '开发者账号无效',
|
|
246
|
+
'201': '请求被拒绝',
|
|
247
|
+
'202': '请求被拒绝',
|
|
248
|
+
'203': '请求被拒绝',
|
|
249
|
+
'301': '词典查询失败',
|
|
250
|
+
'302': '翻译查询失败',
|
|
251
|
+
'303': '服务端的其他异常',
|
|
252
|
+
'401': '账户余额不足',
|
|
253
|
+
'411': '访问频率受限',
|
|
254
|
+
'412': '请求长度受限',
|
|
255
|
+
'1001': '无效的apikey',
|
|
256
|
+
'1002': 'apikey已过期',
|
|
257
|
+
'1003': 'apikey已过期',
|
|
258
|
+
'1004': 'apikey已过期',
|
|
259
|
+
'1005': 'apikey已过期',
|
|
260
|
+
'1006': 'apikey已过期',
|
|
261
|
+
'1007': 'apikey已过期',
|
|
262
|
+
'1008': 'apikey已过期',
|
|
263
|
+
'1009': 'apikey已过期',
|
|
264
|
+
'1010': 'apikey已过期',
|
|
265
|
+
'1011': 'apikey已过期',
|
|
266
|
+
'1012': 'apikey已过期',
|
|
267
|
+
'1013': 'apikey已过期',
|
|
268
|
+
'1014': 'apikey已过期',
|
|
269
|
+
'1015': 'apikey已过期',
|
|
270
|
+
'1016': 'apikey已过期',
|
|
271
|
+
'1017': 'apikey已过期',
|
|
272
|
+
'1018': 'apikey已过期',
|
|
273
|
+
'1019': 'apikey已过期',
|
|
274
|
+
'1020': 'apikey已过期',
|
|
275
|
+
'1021': 'apikey已过期',
|
|
276
|
+
'1022': 'apikey已过期',
|
|
277
|
+
'1023': 'apikey已过期',
|
|
278
|
+
'1024': 'apikey已过期',
|
|
279
|
+
'1025': 'apikey已过期',
|
|
280
|
+
'1026': 'apikey已过期',
|
|
281
|
+
'1027': 'apikey已过期',
|
|
282
|
+
'1028': 'apikey已过期',
|
|
283
|
+
'1029': 'apikey已过期',
|
|
284
|
+
'1030': 'apikey已过期',
|
|
285
|
+
'1031': 'apikey已过期',
|
|
286
|
+
'1032': 'apikey已过期',
|
|
287
|
+
'1033': 'apikey已过期',
|
|
288
|
+
'1034': 'apikey已过期',
|
|
289
|
+
'1035': 'apikey已过期',
|
|
290
|
+
'1036': 'apikey已过期',
|
|
291
|
+
'1037': 'apikey已过期',
|
|
292
|
+
'1038': 'apikey已过期',
|
|
293
|
+
'1039': 'apikey已过期',
|
|
294
|
+
'1040': 'apikey已过期',
|
|
295
|
+
'1041': 'apikey已过期',
|
|
296
|
+
'1042': 'apikey已过期',
|
|
297
|
+
'1043': 'apikey已过期',
|
|
298
|
+
'1044': 'apikey已过期',
|
|
299
|
+
'1045': 'apikey已过期',
|
|
300
|
+
'1046': 'apikey已过期',
|
|
301
|
+
'1047': 'apikey已过期',
|
|
302
|
+
'1048': 'apikey已过期',
|
|
303
|
+
'1049': 'apikey已过期',
|
|
304
|
+
'1050': 'apikey已过期',
|
|
305
|
+
'1051': 'apikey已过期',
|
|
306
|
+
'1052': 'apikey已过期',
|
|
307
|
+
'1053': 'apikey已过期',
|
|
308
|
+
'1054': 'apikey已过期',
|
|
309
|
+
'1055': 'apikey已过期',
|
|
310
|
+
'1056': 'apikey已过期',
|
|
311
|
+
'1057': 'apikey已过期',
|
|
312
|
+
'1058': 'apikey已过期',
|
|
313
|
+
'1059': 'apikey已过期',
|
|
314
|
+
'1060': 'apikey已过期',
|
|
315
|
+
'1061': 'apikey已过期',
|
|
316
|
+
'1062': 'apikey已过期',
|
|
317
|
+
'1063': 'apikey已过期',
|
|
318
|
+
'1064': 'apikey已过期',
|
|
319
|
+
'1065': 'apikey已过期',
|
|
320
|
+
'1066': 'apikey已过期',
|
|
321
|
+
'1067': 'apikey已过期',
|
|
322
|
+
'1068': 'apikey已过期',
|
|
323
|
+
'1069': 'apikey已过期',
|
|
324
|
+
'1070': 'apikey已过期',
|
|
325
|
+
'1071': 'apikey已过期',
|
|
326
|
+
'1072': 'apikey已过期',
|
|
327
|
+
'1073': 'apikey已过期',
|
|
328
|
+
'1074': 'apikey已过期',
|
|
329
|
+
'1075': 'apikey已过期',
|
|
330
|
+
'1076': 'apikey已过期',
|
|
331
|
+
'1077': 'apikey已过期',
|
|
332
|
+
'1078': 'apikey已过期',
|
|
333
|
+
'1079': 'apikey已过期',
|
|
334
|
+
'1080': 'apikey已过期',
|
|
335
|
+
'1081': 'apikey已过期',
|
|
336
|
+
'1082': 'apikey已过期',
|
|
337
|
+
'1083': 'apikey已过期',
|
|
338
|
+
'1084': 'apikey已过期',
|
|
339
|
+
'1085': 'apikey已过期',
|
|
340
|
+
'1086': 'apikey已过期',
|
|
341
|
+
'1087': 'apikey已过期',
|
|
342
|
+
'1088': 'apikey已过期',
|
|
343
|
+
'1089': 'apikey已过期',
|
|
344
|
+
'1090': 'apikey已过期',
|
|
345
|
+
'1091': 'apikey已过期',
|
|
346
|
+
'1092': 'apikey已过期',
|
|
347
|
+
'1093': 'apikey已过期',
|
|
348
|
+
'1094': 'apikey已过期',
|
|
349
|
+
'1095': 'apikey已过期',
|
|
350
|
+
'1096': 'apikey已过期',
|
|
351
|
+
'1097': 'apikey已过期',
|
|
352
|
+
'1098': 'apikey已过期',
|
|
353
|
+
'1099': 'apikey已过期',
|
|
354
|
+
'1100': 'apikey已过期'
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
return errorMessages[errorCode] || '未知错误';
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
module.exports = YoudaoTranslator;
|
package/lib/utils/config.js
CHANGED
|
@@ -206,7 +206,64 @@ class ConfigManager {
|
|
|
206
206
|
lang: {
|
|
207
207
|
defaultLang: "en",
|
|
208
208
|
defaultDir: "./public/locales",
|
|
209
|
-
fileName: "common.json"
|
|
209
|
+
fileName: "common.json",
|
|
210
|
+
|
|
211
|
+
// 翻译引擎配置
|
|
212
|
+
translation: {
|
|
213
|
+
// 默认翻译引擎 (microsoft, google, baidu, ali, youdao, deepl, openai)
|
|
214
|
+
defaultEngine: "microsoft",
|
|
215
|
+
|
|
216
|
+
// 引擎优先级列表(按顺序尝试)
|
|
217
|
+
enginePriority: ["microsoft", "google", "baidu", "ali", "youdao", "deepl", "openai"],
|
|
218
|
+
|
|
219
|
+
// 各引擎API配置
|
|
220
|
+
engines: {
|
|
221
|
+
// 微软翻译(免费,无需配置)
|
|
222
|
+
microsoft: {
|
|
223
|
+
enabled: true
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
// Google翻译(免费,无需配置)
|
|
227
|
+
google: {
|
|
228
|
+
enabled: true
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
// 百度翻译(需要API密钥)
|
|
232
|
+
baidu: {
|
|
233
|
+
enabled: false,
|
|
234
|
+
appId: "", // 百度翻译API App ID
|
|
235
|
+
appKey: "" // 百度翻译API App Key
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
// 阿里云翻译(需要API密钥)
|
|
239
|
+
ali: {
|
|
240
|
+
enabled: false,
|
|
241
|
+
accessKeyId: "", // 阿里云AccessKey ID
|
|
242
|
+
accessKeySecret: "" // 阿里云AccessKey Secret
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
// 有道翻译(需要API密钥)
|
|
246
|
+
youdao: {
|
|
247
|
+
enabled: false,
|
|
248
|
+
appId: "", // 有道翻译API App ID
|
|
249
|
+
appKey: "" // 有道翻译API App Key
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
// DeepL翻译(需要API密钥)
|
|
253
|
+
deepl: {
|
|
254
|
+
enabled: false,
|
|
255
|
+
apiKey: "" // DeepL API Key
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
// OpenAI翻译(需要API密钥)
|
|
259
|
+
openai: {
|
|
260
|
+
enabled: false,
|
|
261
|
+
apiKey: "", // OpenAI API Key
|
|
262
|
+
model: "gpt-3.5-turbo", // 使用的模型
|
|
263
|
+
baseUrl: "https://api.openai.com/v1" // API基础URL
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
210
267
|
}
|
|
211
268
|
}`;
|
|
212
269
|
|
|
@@ -218,7 +275,20 @@ class ConfigManager {
|
|
|
218
275
|
lang: {
|
|
219
276
|
defaultLang: "en",
|
|
220
277
|
defaultDir: "./public/locales",
|
|
221
|
-
fileName: "common.json"
|
|
278
|
+
fileName: "common.json",
|
|
279
|
+
translation: {
|
|
280
|
+
defaultEngine: "microsoft",
|
|
281
|
+
enginePriority: ["microsoft", "google", "baidu", "ali", "youdao", "deepl", "openai"],
|
|
282
|
+
engines: {
|
|
283
|
+
microsoft: { enabled: true },
|
|
284
|
+
google: { enabled: true },
|
|
285
|
+
baidu: { enabled: false, appId: "", appKey: "" },
|
|
286
|
+
ali: { enabled: false, accessKeyId: "", accessKeySecret: "" },
|
|
287
|
+
youdao: { enabled: false, appId: "", appKey: "" },
|
|
288
|
+
deepl: { enabled: false, apiKey: "" },
|
|
289
|
+
openai: { enabled: false, apiKey: "", model: "gpt-3.5-turbo", baseUrl: "https://api.openai.com/v1" }
|
|
290
|
+
}
|
|
291
|
+
}
|
|
222
292
|
}
|
|
223
293
|
};
|
|
224
294
|
|
|
@@ -330,6 +400,33 @@ class ConfigManager {
|
|
|
330
400
|
return this.getCommandConfig('lang');
|
|
331
401
|
}
|
|
332
402
|
|
|
403
|
+
/**
|
|
404
|
+
* 获取翻译配置
|
|
405
|
+
*/
|
|
406
|
+
getTranslationConfig() {
|
|
407
|
+
const langConfig = this.getCommandConfig('lang');
|
|
408
|
+
return langConfig?.translation || {};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* 获取指定引擎的配置
|
|
413
|
+
*/
|
|
414
|
+
getEngineConfig(engineName) {
|
|
415
|
+
const translationConfig = this.getTranslationConfig();
|
|
416
|
+
return translationConfig?.engines?.[engineName] || {};
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* 获取启用的引擎列表(按enginePriority顺序)
|
|
421
|
+
*/
|
|
422
|
+
getEnabledEngines() {
|
|
423
|
+
const translationConfig = this.getTranslationConfig();
|
|
424
|
+
const engines = translationConfig?.engines || {};
|
|
425
|
+
const enginePriority = translationConfig?.enginePriority || [];
|
|
426
|
+
|
|
427
|
+
return enginePriority.filter(engineName => engines[engineName]?.enabled);
|
|
428
|
+
}
|
|
429
|
+
|
|
333
430
|
/**
|
|
334
431
|
* 获取Jenkins配置(向后兼容)
|
|
335
432
|
*/
|