chengjie 2 月之前
父节点
当前提交
581212135d

+ 100 - 0
src/api/yjbdc/machineTranslation.js

@@ -0,0 +1,100 @@
1
+import axios from 'axios';
2
+import crypto from 'crypto';
3
+
4
+// 腾讯云翻译API配置
5
+const TENCENT_TRANSLATE_API = {
6
+  url: 'https://tmt.tencentcloudapi.com/',
7
+  secretId: 'AKID2GI7i7JH2av3yf9RVfkeMn6C5lMk0591',
8
+  secretKey: 'qUzMXYMxKUQ9eFnBNM9zgCZlmbHm6DDC',
9
+  region: 'ap-shanghai',
10
+  projectId: 0,
11
+};
12
+
13
+// 生成腾讯云API签名
14
+function generateTencentCloudSignature(secretKey, timestamp, date, payload) {
15
+  // 步骤1: 拼接规范请求串
16
+  const httpRequestMethod = 'POST';
17
+  const canonicalUri = '/';
18
+  const canonicalQueryString = '';
19
+  const contentType = 'application/json';
20
+  const canonicalHeaders = `content-type:${contentType}\nhost:tmt.tencentcloudapi.com\n`;
21
+  const signedHeaders = 'content-type;host';
22
+  const hashedRequestPayload = crypto.createHash('sha256').update(JSON.stringify(payload)).digest('hex');
23
+  const canonicalRequest = `${httpRequestMethod}\n${canonicalUri}\n${canonicalQueryString}\n${canonicalHeaders}\n${signedHeaders}\n${hashedRequestPayload}`;
24
+  
25
+  // 步骤2: 拼接待签名字符串
26
+  const algorithm = 'TC3-HMAC-SHA256';
27
+  const credentialScope = `${date}/tmt/tc3_request`;
28
+  const hashedCanonicalRequest = crypto.createHash('sha256').update(canonicalRequest).digest('hex');
29
+  const stringToSign = `${algorithm}\n${timestamp}\n${credentialScope}\n${hashedCanonicalRequest}`;
30
+  
31
+  // 步骤3: 计算签名
32
+  const secretDate = crypto.createHmac('sha256', `TC3${secretKey}`).update(date).digest();
33
+  const secretService = crypto.createHmac('sha256', secretDate).update('tmt').digest();
34
+  const secretSigning = crypto.createHmac('sha256', secretService).update('tc3_request').digest();
35
+  const signature = crypto.createHmac('sha256', secretSigning).update(stringToSign).digest('hex');
36
+  
37
+  return signature;
38
+}
39
+
40
+// 腾讯云翻译API
41
+async function translateText(text, sourceLang = 'en', targetLang = 'zh') {
42
+  try {
43
+    const timestamp = Math.floor(Date.now() / 1000);
44
+    const date = new Date().toISOString().split('T')[0];
45
+    
46
+    const payload = {
47
+      SourceText: text,
48
+      Source: sourceLang,
49
+      Target: targetLang,
50
+      ProjectId: TENCENT_TRANSLATE_API.projectId,
51
+    };
52
+    
53
+    const signature = generateTencentCloudSignature(
54
+      TENCENT_TRANSLATE_API.secretKey,
55
+      timestamp,
56
+      date,
57
+      payload
58
+    );
59
+    
60
+    const authorization = `TC3-HMAC-SHA256 Credential=${TENCENT_TRANSLATE_API.secretId}/${date}/tmt/tc3_request, SignedHeaders=content-type;host, Signature=${signature}`;
61
+    
62
+    const response = await axios.post(
63
+      TENCENT_TRANSLATE_API.url,
64
+      payload,
65
+      {
66
+        headers: {
67
+          'Content-Type': 'application/json',
68
+          'Host': 'tmt.tencentcloudapi.com',
69
+          'X-TC-Action': 'TextTranslate',
70
+          'X-TC-Version': '2018-03-21',
71
+          'X-TC-Region': TENCENT_TRANSLATE_API.region,
72
+          'X-TC-Timestamp': timestamp,
73
+          'Authorization': authorization,
74
+        },
75
+      }
76
+    );
77
+    
78
+    return {
79
+      success: true,
80
+      data: response.data.Response.TargetText,
81
+    };
82
+  } catch (error) {
83
+    console.error('翻译失败:', error.message);
84
+    if (error.response) {
85
+      console.error('错误详情:', JSON.stringify(error.response.data));
86
+    }
87
+    return {
88
+      success: false,
89
+      error: error.message,
90
+      originalText: text,
91
+    };
92
+  }
93
+}
94
+
95
+// 导出API
96
+const machineTranslationAPI = {
97
+  translateText,
98
+};
99
+
100
+export default machineTranslationAPI;

+ 1 - 0
src/api/yjbdc/routes.js

@@ -17,6 +17,7 @@ router.get('/api/DeleteYJBDCArticleList',yjbdcController.DeleteYJBDCArticleList)
17 17
 router.get('/api/UpdateYJBDCArticleReadCount',yjbdcController.UpdateYJBDCArticleReadCount);
18 18
 router.get('/api/GetWordChinese',yjbdcController.GetWordChinese);
19 19
 router.get('/api/GetWordDetail',yjbdcController.GetWordDetail);
20
+router.post('/api/GetSentenceTranslate',yjbdcController.GetSentenceTranslate);
20 21
 
21 22
 router.get('/api/AddOrDeleteYJBDCUserCollect',yjbdcController.AddOrDeleteYJBDCUserCollect);
22 23
 router.get('/api/DeleteYJBDCUserCollect',yjbdcController.DeleteYJBDCUserCollect);

+ 9 - 0
src/api/yjbdc/yjbdcController.js

@@ -12,6 +12,7 @@ import { globalCache } from '../../util/GlobalCache.js';
12 12
 import constantClass from '../../util/constant/index.js';
13 13
 import yjbdc from '../../model/yjbdc.js';
14 14
 import aiController from './aiController.js';
15
+import machineTranslationAPI from './machineTranslation.js';
15 16
 
16 17
 import PDFDocument from 'pdfkit';
17 18
 import tencentcloud from 'tencentcloud-sdk-nodejs-ocr';
@@ -1381,3 +1382,11 @@ export async function YJBDC_Articles_Admin(ctx) {
1381 1382
     const data = await fsPromises.readFile("./public/mg/yjbdc_articles.html");
1382 1383
     ctx.body = data.toString();
1383 1384
 };
1385
+
1386
+export async function GetSentenceTranslate(ctx) {
1387
+    const param = ctx.request.body;
1388
+    // 调用翻译API
1389
+    const result = await machineTranslationAPI.translateText(param.Sentence);
1390
+    console.log(result);
1391
+    ctx.body = { "errcode": 10000, result: result.data };
1392
+};

+ 3 - 3
src/web_crawler/crawle_english.js

@@ -14,9 +14,9 @@ const __dirname = path.dirname(__filename);
14 14
 const WEB_URL=`https://novelhi.com`;
15 15
 const WEB_URL_INDEX=`/s/index/`;
16 16
 
17
-const title = "Throne-of-Magical-Arcana";
18
-const author = "Cuttlefish That Loves Diving";
19
-const coverName = "cover.jpg";
17
+const title = "Strange-Life-of-a-Cat";
18
+const author = "Lazy Cliché";
19
+const coverName = "cover.jpeg";
20 20
 
21 21
 /**
22 22
  * 检查章节文件是否已存在

文件差异内容过多而无法显示
+ 1012 - 0
src/web_crawler/crawle_english2.js