daodou-command 1.3.0 → 1.4.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 (42) hide show
  1. package/.daodourc.example +85 -0
  2. package/.idea/UniappTool.xml +10 -0
  3. package/.idea/copilot.data.migration.agent.xml +6 -0
  4. package/.idea/copilot.data.migration.ask.xml +6 -0
  5. package/.idea/copilot.data.migration.ask2agent.xml +6 -0
  6. package/.idea/copilot.data.migration.edit.xml +6 -0
  7. package/.idea/daodou-command.iml +12 -0
  8. package/.idea/editorJumperProjectSettings.xml +6 -0
  9. package/.idea/modules.xml +8 -0
  10. package/.idea/vcs.xml +6 -0
  11. package/.idea/workspace.xml +72 -0
  12. package/CHANGELOG.md +17 -3
  13. package/README.md +45 -2
  14. package/lib/commands/config.js +57 -3
  15. package/lib/commands/lang.js +2 -1
  16. package/lib/translation/TranslationService.js +208 -0
  17. package/lib/translation/engines/BaseTranslator.js +90 -0
  18. package/lib/translation/engines/ali/AliTranslator.js +316 -0
  19. package/lib/translation/engines/ali/index.js +8 -0
  20. package/lib/translation/engines/baidu/BaiduTranslator.js +209 -0
  21. package/lib/translation/engines/baidu/index.js +8 -0
  22. package/lib/translation/engines/deepl/DeeplTranslator.js +234 -0
  23. package/lib/translation/engines/deepl/index.js +8 -0
  24. package/lib/translation/engines/google/GoogleTranslator.js +251 -0
  25. package/lib/translation/engines/google/index.js +8 -0
  26. package/lib/translation/engines/index.js +69 -0
  27. package/lib/translation/engines/microsoft/MicrosoftTranslator.js +190 -0
  28. package/lib/translation/engines/microsoft/index.js +6 -0
  29. package/lib/translation/engines/microsoft/services/EdgeAuthService.js +166 -0
  30. package/lib/translation/engines/microsoft/services/HttpClient.js +93 -0
  31. package/lib/translation/engines/microsoft/services/TranslatorService.js +167 -0
  32. package/lib/translation/engines/microsoft/types/index.js +147 -0
  33. package/lib/translation/engines/openai/OpenaiTranslator.js +363 -0
  34. package/lib/translation/engines/openai/index.js +8 -0
  35. package/lib/translation/engines/youdao/YoudaoTranslator.js +361 -0
  36. package/lib/translation/engines/youdao/index.js +8 -0
  37. package/lib/translation/index.js +10 -0
  38. package/lib/utils/config.js +99 -2
  39. package/lib/utils/translation.js +58 -100
  40. package/package.json +1 -3
  41. package/.daodourc +0 -25
  42. package/lib/utils/proxy-manager.js +0 -364
@@ -0,0 +1,85 @@
1
+ {
2
+ // build 命令配置
3
+ build: {
4
+ // Jenkins 基础配置
5
+ // jenkinsUrl: "https://jenkins.example.com/",
6
+ // jenkinsBase: "https://jenkins.example.com/job",
7
+ // jenkinsToken: "your-jenkins-token",
8
+ // jenkinsUsername: "your-username",
9
+ // jenkinsPassword: "your-password",
10
+
11
+ // 构建任务配置(必须配置)
12
+ // jobName: "your-job-name", // 必须配置的任务名称
13
+
14
+ // 构建参数配置
15
+ // buildParams: {
16
+ // token: "your-jenkins-token",
17
+ // BUILD_ENV: "test",
18
+ // version: "0.0.1"
19
+ // }
20
+ },
21
+
22
+ // lang 命令配置
23
+ lang: {
24
+ defaultLang: "en",
25
+ defaultDir: "./public/locales",
26
+ fileName: "common.json",
27
+
28
+ // 翻译引擎配置
29
+ translation: {
30
+ // 默认翻译引擎 (microsoft, google, baidu, ali, youdao, deepl, openai)
31
+ defaultEngine: "microsoft",
32
+
33
+ // 引擎优先级列表(按顺序尝试)
34
+ enginePriority: ["microsoft", "google", "baidu", "ali", "youdao", "deepl", "openai"],
35
+
36
+ // 各引擎API配置
37
+ engines: {
38
+ // 微软翻译(免费,无需配置)
39
+ microsoft: {
40
+ enabled: true
41
+ },
42
+
43
+ // Google翻译(免费,无需配置)
44
+ google: {
45
+ enabled: true
46
+ },
47
+
48
+ // 百度翻译(需要API密钥)
49
+ baidu: {
50
+ enabled: false,
51
+ appId: "", // 百度翻译API App ID
52
+ appKey: "" // 百度翻译API App Key
53
+ },
54
+
55
+ // 阿里云翻译(需要API密钥)
56
+ ali: {
57
+ enabled: false,
58
+ accessKeyId: "", // 阿里云AccessKey ID
59
+ accessKeySecret: "" // 阿里云AccessKey Secret
60
+ },
61
+
62
+ // 有道翻译(需要API密钥)
63
+ youdao: {
64
+ enabled: false,
65
+ appId: "", // 有道翻译API App ID
66
+ appKey: "" // 有道翻译API App Key
67
+ },
68
+
69
+ // DeepL翻译(需要API密钥)
70
+ deepl: {
71
+ enabled: false,
72
+ apiKey: "" // DeepL API Key
73
+ },
74
+
75
+ // OpenAI翻译(需要API密钥)
76
+ openai: {
77
+ enabled: false,
78
+ apiKey: "", // OpenAI API Key
79
+ model: "gpt-3.5-turbo", // 使用的模型
80
+ baseUrl: "https://api.openai.com/v1" // API基础URL
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="cn.fjdmy.uniapp.UniappProjectDataService">
4
+ <option name="generalBasePath" value="$PROJECT_DIR$" />
5
+ <option name="manifestPath" value="$PROJECT_DIR$/manifest.json" />
6
+ <option name="pagesPath" value="$PROJECT_DIR$/pages.json" />
7
+ <option name="scanNum" value="1" />
8
+ <option name="type" value="store" />
9
+ </component>
10
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AgentMigrationStateService">
4
+ <option name="migrationStatus" value="COMPLETED" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AskMigrationStateService">
4
+ <option name="migrationStatus" value="COMPLETED" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Ask2AgentMigrationStateService">
4
+ <option name="migrationStatus" value="COMPLETED" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="EditMigrationStateService">
4
+ <option name="migrationStatus" value="COMPLETED" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
+ <excludeFolder url="file://$MODULE_DIR$/temp" />
7
+ <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
+ </content>
9
+ <orderEntry type="inheritedJdk" />
10
+ <orderEntry type="sourceFolder" forTests="false" />
11
+ </component>
12
+ </module>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="com.github.wanniwa.editorjumper.settings.EditorJumperProjectSettings">
4
+ <option name="projectEditorType" value="Cursor" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/daodou-command.iml" filepath="$PROJECT_DIR$/.idea/daodou-command.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,72 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AutoImportSettings">
4
+ <option name="autoReloadType" value="SELECTIVE" />
5
+ </component>
6
+ <component name="ChangeListManager">
7
+ <list default="true" id="1537cb23-f918-4011-a0ed-24da46bf53bc" name="更改" comment="" />
8
+ <option name="SHOW_DIALOG" value="false" />
9
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
10
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
11
+ <option name="LAST_RESOLUTION" value="IGNORE" />
12
+ </component>
13
+ <component name="Git.Settings">
14
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
15
+ </component>
16
+ <component name="GitHubPullRequestSearchHistory"><![CDATA[{
17
+ "lastFilter": {
18
+ "state": "OPEN",
19
+ "assignee": "h025"
20
+ }
21
+ }]]></component>
22
+ <component name="GithubPullRequestsUISettings"><![CDATA[{
23
+ "selectedUrlAndAccountId": {
24
+ "url": "https://github.com/h025/daodou-command.git",
25
+ "accountId": "c8b4f74c-2e36-4aad-b608-940f73fc88db"
26
+ }
27
+ }]]></component>
28
+ <component name="ProjectColorInfo"><![CDATA[{
29
+ "associatedIndex": 6
30
+ }]]></component>
31
+ <component name="ProjectId" id="33EP70DuHXVnueD9LcTKpn8t7Vr" />
32
+ <component name="ProjectViewState">
33
+ <option name="hideEmptyMiddlePackages" value="true" />
34
+ <option name="showLibraryContents" value="true" />
35
+ </component>
36
+ <component name="PropertiesComponent"><![CDATA[{
37
+ "keyToString": {
38
+ "ModuleVcsDetector.initialDetectionPerformed": "true",
39
+ "RunOnceActivity.ShowReadmeOnStart": "true",
40
+ "RunOnceActivity.git.unshallow": "true",
41
+ "git-widget-placeholder": "main",
42
+ "last_opened_file_path": "/Users/summermr/daodou/daodou-command",
43
+ "node.js.detected.package.eslint": "true",
44
+ "node.js.detected.package.tslint": "true",
45
+ "node.js.selected.package.eslint": "(autodetect)",
46
+ "node.js.selected.package.tslint": "(autodetect)",
47
+ "nodejs_package_manager_path": "npm",
48
+ "vue.rearranger.settings.migration": "true"
49
+ }
50
+ }]]></component>
51
+ <component name="SharedIndexes">
52
+ <attachedChunks>
53
+ <set>
54
+ <option value="bundled-js-predefined-d6986cc7102b-9c94529fcfe0-JavaScript-WS-252.26199.162" />
55
+ </set>
56
+ </attachedChunks>
57
+ </component>
58
+ <component name="TaskManager">
59
+ <task active="true" id="Default" summary="默认任务">
60
+ <changelist id="1537cb23-f918-4011-a0ed-24da46bf53bc" name="更改" comment="" />
61
+ <created>1758879086844</created>
62
+ <option name="number" value="Default" />
63
+ <option name="presentableId" value="Default" />
64
+ <updated>1758879086844</updated>
65
+ <workItem from="1758879088110" duration="1148000" />
66
+ </task>
67
+ <servers />
68
+ </component>
69
+ <component name="TypeScriptGeneratedFilesManager">
70
+ <option name="version" value="3" />
71
+ </component>
72
+ </project>
package/CHANGELOG.md CHANGED
@@ -5,12 +5,26 @@
5
5
  格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
6
6
  并且此项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
7
7
 
8
- ## [未发布]
8
+ ## [1.4.1]
9
+
10
+ ### 修复
11
+ - 移除翻译服务初始化时的冗余输出信息,提升用户体验
12
+
13
+ ## [1.4.0] - 2025-09-26
9
14
 
10
15
  ### 新增
16
+ - 实现7种翻译引擎:微软、Google、百度、阿里云、有道、DeepL、OpenAI
17
+ - 支持多引擎配置和优先级调度
18
+ - HTML文档翻译支持,保持标签结构完整
19
+ - 智能引擎故障转移和重试机制
20
+ - 灵活的API密钥配置管理
21
+
11
22
  ### 更改
12
- ### 修复
13
- ### 移除
23
+ - 重构翻译服务架构,支持多引擎调度
24
+ - 优化配置文件结构,翻译引擎配置移至lang命令下
25
+ - 简化配置结构,移除重复的priority字段,统一使用enginePriority
26
+ - 自动生成配置时包含完整的翻译引擎配置
27
+ - 提升翻译服务的稳定性和可靠性
14
28
 
15
29
  ## [1.3.0] - 2025-09-16
16
30
 
package/README.md CHANGED
@@ -17,8 +17,10 @@ npm install -g daodou-command
17
17
 
18
18
  ### 🌐 多语言管理
19
19
  - 支持多语言文件管理
20
- - 自动翻译功能(Google Translate API
21
- - 多代理轮换绕过API限制
20
+ - 多引擎翻译支持(微软、Google、百度、阿里云、有道、DeepL、OpenAI
21
+ - HTML文档翻译支持,保持标签结构
22
+ - 智能引擎调度和故障转移
23
+ - 灵活的引擎配置和优先级设置
22
24
 
23
25
  ### 🔄 自动更新
24
26
  - 智能版本检查和更新
@@ -66,6 +68,47 @@ dao config edit
66
68
  dao config clear
67
69
  ```
68
70
 
71
+ ### 翻译引擎配置
72
+ 支持7种翻译引擎,可在lang命令配置中灵活配置:
73
+
74
+ ```json
75
+ {
76
+ "lang": {
77
+ "defaultLang": "en",
78
+ "defaultDir": "./public/locales",
79
+ "fileName": "common.json",
80
+ "translation": {
81
+ "defaultEngine": "microsoft",
82
+ "enginePriority": ["microsoft", "google", "baidu", "ali", "youdao", "deepl", "openai"],
83
+ "engines": {
84
+ "microsoft": { "enabled": true },
85
+ "google": { "enabled": true },
86
+ "baidu": { "enabled": false, "appId": "", "appKey": "" },
87
+ "ali": { "enabled": false, "accessKeyId": "", "accessKeySecret": "" },
88
+ "youdao": { "enabled": false, "appId": "", "appKey": "" },
89
+ "deepl": { "enabled": false, "apiKey": "" },
90
+ "openai": { "enabled": false, "apiKey": "", "model": "gpt-3.5-turbo" }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ **支持的翻译引擎:**
98
+ - **微软翻译**: 免费,无需配置,支持HTML翻译
99
+ - **Google翻译**: 免费,无需配置,支持HTML翻译
100
+ - **百度翻译**: 需要App ID和App Key
101
+ - **阿里云翻译**: 需要AccessKey ID和AccessKey Secret,支持HTML翻译
102
+ - **有道翻译**: 需要App ID和App Key
103
+ - **DeepL翻译**: 需要API Key
104
+ - **OpenAI翻译**: 需要API Key和模型配置,支持HTML翻译
105
+
106
+ **HTML翻译支持:**
107
+ - 微软翻译:原生支持HTML格式,保持标签结构
108
+ - Google翻译:支持HTML格式翻译
109
+ - 阿里云翻译:支持HTML格式翻译
110
+ - OpenAI翻译:智能识别HTML标签,保持结构完整
111
+
69
112
  ### 多语言管理
70
113
  ```bash
71
114
  # 添加多语言项(自动翻译)
@@ -303,9 +303,63 @@ class ConfigCommand {
303
303
  defaultLang: "en",
304
304
  defaultDir: "./public/locales",
305
305
  fileName: "common.json",
306
- // 代理相关配置(全局默认)
307
- proxyListUrl: "https://free-proxy-list.net/",
308
- proxyTestUrl: "https://httpbin.org/ip"
306
+
307
+ // 翻译引擎配置
308
+ translation: {
309
+ // 默认翻译引擎 (microsoft, google, baidu, ali, youdao, deepl, openai)
310
+ defaultEngine: "microsoft",
311
+
312
+ // 引擎优先级列表(按顺序尝试)
313
+ enginePriority: ["microsoft", "google", "baidu", "ali", "youdao", "deepl", "openai"],
314
+
315
+ // 各引擎API配置
316
+ engines: {
317
+ // 微软翻译(免费,无需配置)
318
+ microsoft: {
319
+ enabled: true
320
+ },
321
+
322
+ // Google翻译(免费,无需配置)
323
+ google: {
324
+ enabled: true
325
+ },
326
+
327
+ // 百度翻译(需要API密钥)
328
+ baidu: {
329
+ enabled: false,
330
+ appId: "", // 百度翻译API App ID
331
+ appKey: "" // 百度翻译API App Key
332
+ },
333
+
334
+ // 阿里云翻译(需要API密钥)
335
+ ali: {
336
+ enabled: false,
337
+ accessKeyId: "", // 阿里云AccessKey ID
338
+ accessKeySecret: "" // 阿里云AccessKey Secret
339
+ },
340
+
341
+ // 有道翻译(需要API密钥)
342
+ youdao: {
343
+ enabled: false,
344
+ appId: "", // 有道翻译API App ID
345
+ appKey: "" // 有道翻译API App Key
346
+ },
347
+
348
+ // DeepL翻译(需要API密钥)
349
+ deepl: {
350
+ enabled: false,
351
+ apiKey: "" // DeepL API Key
352
+ },
353
+
354
+ // OpenAI翻译(需要API密钥)
355
+ openai: {
356
+ enabled: false,
357
+ apiKey: "", // OpenAI API Key
358
+ model: "gpt-3.5-turbo", // 使用的模型
359
+ baseUrl: "https://api.openai.com/v1" // API基础URL
360
+ }
361
+ }
362
+ }
309
363
  }
310
364
  }`;
311
365
 
@@ -154,9 +154,10 @@ class LangCommand {
154
154
  this.translationService.showProxyStats();
155
155
 
156
156
  console.log(chalk.blue('\n📋 翻译结果汇总:'));
157
+ console.log(chalk.gray(`原文: "${finalValue}"`));
157
158
  for (const [lang, result] of Object.entries(results)) {
158
159
  if (result.status === 'success') {
159
- console.log(chalk.green(` ${lang}: "${key}": "${result.value}"`));
160
+ console.log(chalk.green(` ${lang}: ${result.value}`));
160
161
  } else if (result.status === 'skipped') {
161
162
  console.log(chalk.yellow(` ${lang}: 跳过 (${result.reason})`));
162
163
  } else {
@@ -0,0 +1,208 @@
1
+ /**
2
+ * 主翻译服务调度器
3
+ * 支持多引擎调度和配置管理
4
+ */
5
+ const { getEnginesByPriority, getEnabledEngines } = require('./engines');
6
+ const { ConfigManager } = require('../utils/config');
7
+ const chalk = require('chalk');
8
+
9
+ class TranslationService {
10
+ constructor() {
11
+ this.configManager = new ConfigManager();
12
+ this.config = this.configManager.getAll();
13
+
14
+ // 根据配置获取启用的引擎
15
+ this.engines = getEnabledEngines(this.config);
16
+
17
+ // 如果没有启用的引擎,使用默认的微软翻译
18
+ if (this.engines.length === 0) {
19
+ const MicrosoftTranslator = require('./engines/microsoft/MicrosoftTranslator');
20
+ this.engines = [new MicrosoftTranslator()];
21
+ }
22
+ }
23
+
24
+ /**
25
+ * 翻译文本
26
+ * @param {string} text - 要翻译的文本
27
+ * @param {string} sourceLang - 源语言代码
28
+ * @param {string} targetLang - 目标语言代码
29
+ * @param {object} options - 翻译选项
30
+ * @returns {Promise<object>} 翻译结果
31
+ */
32
+ async translate(text, sourceLang, targetLang, options = {}) {
33
+ if (!text || !targetLang) {
34
+ throw new Error('文本和目标语言不能为空');
35
+ }
36
+
37
+ let lastError = null;
38
+
39
+ // 按优先级尝试各个引擎
40
+ for (const engine of this.engines) {
41
+ try {
42
+ console.log(chalk.blue(`尝试使用 ${engine.getName()} 翻译...`));
43
+
44
+ // 检查引擎是否可用
45
+ const isAvailable = await engine.isAvailable();
46
+ if (!isAvailable) {
47
+ console.log(chalk.yellow(`${engine.getName()} 不可用,跳过`));
48
+ continue;
49
+ }
50
+
51
+ // 执行翻译
52
+ const result = await engine.translate(text, sourceLang, targetLang, options);
53
+
54
+ if (result.success) {
55
+ console.log(chalk.green(`翻译成功,使用引擎: ${engine.getName()}`));
56
+ return result;
57
+ }
58
+ } catch (error) {
59
+ console.log(chalk.red(`${engine.getName()} 翻译失败: ${error.message}`));
60
+ lastError = error;
61
+ continue;
62
+ }
63
+ }
64
+
65
+ // 所有引擎都失败了
66
+ throw new Error(`所有翻译引擎都失败了。最后错误: ${lastError?.message || '未知错误'}`);
67
+ }
68
+
69
+ /**
70
+ * 翻译文档
71
+ * @param {string} text - 要翻译的文档内容
72
+ * @param {string} sourceLang - 源语言代码
73
+ * @param {string} targetLang - 目标语言代码
74
+ * @param {object} options - 翻译选项
75
+ * @returns {Promise<object>} 翻译结果
76
+ */
77
+ async translateDocumentation(text, sourceLang, targetLang, options = {}) {
78
+ // 优先使用微软翻译的文档翻译功能
79
+ const microsoftEngine = this.engines.find(engine => engine.getName() === 'Microsoft Translator');
80
+
81
+ if (microsoftEngine && await microsoftEngine.isAvailable()) {
82
+ try {
83
+ console.log(chalk.blue('使用微软翻译文档功能...'));
84
+ return await microsoftEngine.translateDocumentation(text, sourceLang, targetLang, options);
85
+ } catch (error) {
86
+ console.log(chalk.yellow('微软文档翻译失败,回退到普通翻译'));
87
+ }
88
+ }
89
+
90
+ // 回退到普通翻译
91
+ return await this.translate(text, sourceLang, targetLang, options);
92
+ }
93
+
94
+ /**
95
+ * 翻译HTML文档
96
+ * @param {string} htmlContent - 要翻译的HTML内容
97
+ * @param {string} sourceLang - 源语言代码
98
+ * @param {string} targetLang - 目标语言代码
99
+ * @param {object} options - 翻译选项
100
+ * @returns {Promise<object>} 翻译结果
101
+ */
102
+ async translateHtml(htmlContent, sourceLang, targetLang, options = {}) {
103
+ let lastError = null;
104
+
105
+ // 按优先级尝试各个引擎
106
+ for (const engine of this.engines) {
107
+ try {
108
+ console.log(chalk.blue(`尝试使用 ${engine.getName()} 翻译HTML...`));
109
+
110
+ // 检查引擎是否可用
111
+ if (!(await engine.isAvailable())) {
112
+ console.log(chalk.yellow(`引擎 ${engine.getName()} 不可用,跳过`));
113
+ continue;
114
+ }
115
+
116
+ // 执行HTML翻译
117
+ const result = await engine.translateHtml(htmlContent, sourceLang, targetLang, options);
118
+
119
+ if (result && result.success) {
120
+ console.log(chalk.green(`HTML翻译成功,使用引擎: ${engine.getName()}`));
121
+ return result;
122
+ }
123
+
124
+ } catch (error) {
125
+ lastError = error;
126
+ console.log(chalk.red(`引擎 ${engine.getName()} HTML翻译失败: ${error.message}`));
127
+
128
+ // 如果是内容长度限制错误,直接抛出,不尝试其他引擎
129
+ if (error.message.includes('内容过长') || error.message.includes('Content too long')) {
130
+ throw error;
131
+ }
132
+ }
133
+ }
134
+
135
+ // 所有引擎都失败了
136
+ throw new Error(`所有翻译引擎都失败了。最后错误: ${lastError?.message || '未知错误'}`);
137
+ }
138
+
139
+ /**
140
+ * 获取所有支持的语言
141
+ * @returns {Promise<Array>} 支持的语言列表
142
+ */
143
+ async getSupportedLanguages() {
144
+ const allLanguages = new Set();
145
+
146
+ for (const engine of this.engines) {
147
+ try {
148
+ const languages = await engine.getSupportedLanguages();
149
+ languages.forEach(lang => allLanguages.add(lang));
150
+ } catch (error) {
151
+ console.log(chalk.yellow(`获取 ${engine.getName()} 支持语言失败: ${error.message}`));
152
+ }
153
+ }
154
+
155
+ return Array.from(allLanguages).sort();
156
+ }
157
+
158
+ /**
159
+ * 获取引擎状态
160
+ * @returns {Promise<Array>} 引擎状态列表
161
+ */
162
+ async getEngineStatus() {
163
+ const status = [];
164
+
165
+ for (const engine of this.engines) {
166
+ try {
167
+ const isAvailable = await engine.isAvailable();
168
+ status.push({
169
+ name: engine.getName(),
170
+ priority: engine.getPriority(),
171
+ available: isAvailable,
172
+ status: isAvailable ? '可用' : '不可用'
173
+ });
174
+ } catch (error) {
175
+ status.push({
176
+ name: engine.getName(),
177
+ priority: engine.getPriority(),
178
+ available: false,
179
+ status: `错误: ${error.message}`
180
+ });
181
+ }
182
+ }
183
+
184
+ return status.sort((a, b) => a.priority - b.priority);
185
+ }
186
+
187
+ /**
188
+ * 获取代理统计信息(已禁用)
189
+ * @returns {object} 代理统计信息
190
+ */
191
+ getProxyStats() {
192
+ return {
193
+ totalProxies: 0,
194
+ currentIndex: 0,
195
+ hasProxies: false,
196
+ message: '代理功能已禁用,直接使用微软翻译'
197
+ };
198
+ }
199
+
200
+ /**
201
+ * 重置代理列表(已禁用)
202
+ */
203
+ async resetProxies() {
204
+ console.log(chalk.yellow('代理功能已禁用,直接使用微软翻译'));
205
+ }
206
+ }
207
+
208
+ module.exports = TranslationService;