chengjie 4 月之前
父节点
当前提交
dbee55f5c3

+ 123 - 4
src/api/yjbdc/aiController.js

@@ -123,6 +123,71 @@ class OpenAIProvider extends AIProvider {
123 123
     }
124 124
 }
125 125
 
126
+/**
127
+ * 阿里云通义平台实现
128
+ */
129
+class AliyunAIProvider extends AIProvider {
130
+    constructor(model = 'qwen-plus') {
131
+        super();
132
+
133
+        this.accessKey = config.aliyun.accessKey;
134
+        this.headers = {
135
+            "Content-Type": "application/json",
136
+            "Accept": "application/json"
137
+        };
138
+        this.url = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions";
139
+        this.model = model;
140
+    }
141
+
142
+    /**
143
+     * 生成文章
144
+     * @param {string} content - 生成文章的提示内容
145
+     * @returns {Promise<string>} - 返回生成的文章内容
146
+     */
147
+    async generateArticle(content) {
148
+        // 设置请求头中的API密钥
149
+        this.headers["Authorization"] = `Bearer ${this.accessKey}`;
150
+        
151
+        const postJSON = {
152
+            "model": this.model,
153
+            "messages": [
154
+                {
155
+                    "role": "user",
156
+                    "content": content
157
+                }
158
+            ],
159
+            "temperature": 0.7,
160
+            "top_p": 0.8
161
+        };
162
+
163
+        try {
164
+            console.log(`阿里云通义 ${this.model}`);
165
+            const response = await axios.post(this.url, postJSON, { headers: this.headers });
166
+            
167
+            // 根据阿里云通义API的返回格式提取内容
168
+            if (response.data && response.data.choices && response.data.choices[0] && response.data.choices[0].message) {
169
+                let responseContent = response.data.choices[0].message.content;
170
+                
171
+                // 处理可能的Markdown代码块标记
172
+                if (responseContent.startsWith('```json') || responseContent.startsWith('```')) {
173
+                    console.log("阿里云返回了Markdown代码块,正在处理...");
174
+                    // 移除开头的```json或```
175
+                    responseContent = responseContent.replace(/^```(?:json)?\s*\n/, '');
176
+                    // 移除结尾的```
177
+                    responseContent = responseContent.replace(/\n```\s*$/, '');
178
+                }
179
+                
180
+                return responseContent;
181
+            } else {
182
+                throw new Error("Unexpected response format from Aliyun API");
183
+            }
184
+        } catch (error) {
185
+            console.error("Aliyun AI API error:", error);
186
+            throw error;
187
+        }
188
+    }
189
+}
190
+
126 191
 /**
127 192
  * 百度文心一言平台实现
128 193
  */
@@ -195,6 +260,12 @@ class AIProviderFactory {
195 260
             return new VolcesAIProvider(version);
196 261
         }
197 262
         
263
+        // 处理阿里云通义通用提供者格式:aliyun:模型名
264
+        if (providerLower.startsWith('aliyun:')) {
265
+            const model = providerLower.split(':')[1];
266
+            return new AliyunAIProvider(model);
267
+        }
268
+        
198 269
         // 处理传统提供者名称
199 270
         switch (providerLower) {
200 271
             case 'volces':
@@ -204,8 +275,12 @@ class AIProviderFactory {
204 275
                 return new VolcesAIProvider1_6('1-6');
205 276
             case 'openai':
206 277
                 return new OpenAIProvider();
278
+            case 'qwen-plus':
279
+                return new AliyunAIProvider();
207 280
             case 'baidu':
208 281
                 return new BaiduAIProvider();
282
+            case 'aliyun':
283
+                return new AliyunAIProvider(); // 默认使用qwen-turbo模型
209 284
             default:
210 285
                 return new VolcesAIProvider('1-5'); // 默认使用火山云1.5
211 286
         }
@@ -235,15 +310,43 @@ async function generateArticle(content, provider = 'volces1-5') {
235 310
  * @returns {string} - 返回修复后的JSON字符串
236 311
  */
237 312
 function validateAndFixJSON(jsonString) {
313
+    // 如果输入不是字符串,直接返回
314
+    if (typeof jsonString !== 'string') {
315
+        console.error("输入不是字符串类型");
316
+        return jsonString;
317
+    }
318
+    
319
+    // 预处理:移除Markdown代码块标记
320
+    let processedJson = jsonString;
321
+    
322
+    // 检查并移除Markdown代码块标记
323
+    if (processedJson.includes('```')) {
324
+        console.log("检测到Markdown代码块,尝试移除标记");
325
+        
326
+        // 处理可能的多行代码块
327
+        const codeBlockRegex = /```(?:json)?\s*\n([\s\S]*?)\n```/;
328
+        const match = processedJson.match(codeBlockRegex);
329
+        
330
+        if (match && match[1]) {
331
+            // 提取代码块内容
332
+            processedJson = match[1];
333
+            console.log("成功提取代码块内容");
334
+        } else {
335
+            // 如果正则匹配失败,尝试简单替换
336
+            processedJson = processedJson.replace(/^```(?:json)?\s*\n/, '');
337
+            processedJson = processedJson.replace(/\n```\s*$/, '');
338
+        }
339
+    }
340
+    
238 341
     try {
239 342
         // 尝试解析JSON
240
-        const parsed = JSON.parse(jsonString);
241
-        return jsonString;
343
+        const parsed = JSON.parse(processedJson);
344
+        return processedJson;
242 345
     } catch (error) {
243 346
         console.error("JSON解析错误,尝试修复:", error);
244 347
         
245 348
         // 尝试修复常见的JSON错误
246
-        let fixedJson = jsonString;
349
+        let fixedJson = processedJson;
247 350
         
248 351
         // 修复缺少引号的键
249 352
         fixedJson = fixedJson.replace(/(\s*?)(\w+)(\s*?):/g, '"$2":');
@@ -262,7 +365,23 @@ function validateAndFixJSON(jsonString) {
262 365
             return fixedJson;
263 366
         } catch (error2) {
264 367
             console.error("JSON修复失败:", error2);
265
-            // 如果修复失败,返回原始字符串
368
+            
369
+            // 最后尝试:如果内容看起来像JSON但解析失败,尝试提取{}之间的内容
370
+            const jsonObjectRegex = /\{[\s\S]*\}/;
371
+            const objectMatch = jsonString.match(jsonObjectRegex);
372
+            
373
+            if (objectMatch) {
374
+                try {
375
+                    const extractedJson = objectMatch[0];
376
+                    JSON.parse(extractedJson);
377
+                    console.log("通过提取{}内容成功修复JSON");
378
+                    return extractedJson;
379
+                } catch (error3) {
380
+                    console.error("提取{}内容后仍解析失败");
381
+                }
382
+            }
383
+            
384
+            // 如果所有尝试都失败,返回原始字符串
266 385
             return jsonString;
267 386
         }
268 387
     }

+ 192 - 0
src/api/yjbdc/enhanceFormsOfWords.js

@@ -84,6 +84,193 @@ export function enhanceFormsOfWords(jsonObj, userWords) {
84 84
     // 常见的后缀列表
85 85
     const commonSuffixes = ['ed', 'ing', 's', 'es', 'er', 'est', 'ly'];
86 86
     
87
+    /**
88
+     * 检查单词是否符合特定的变形规则
89
+     * @param {string} word - 要检查的单词
90
+     * @param {string} base - 基本形式
91
+     * @returns {boolean} - 是否符合变形规则
92
+     */
93
+    function checkSpecialWordForms(word, base) {
94
+        // 处理以y结尾的单词变为复数时,y变为ies的情况 (如cry -> cries)
95
+        if (base.endsWith('y') && word === base.slice(0, -1) + 'ies') {
96
+            return true;
97
+        }
98
+        
99
+        // 处理以fe结尾的单词变为复数时,fe变为ves的情况 (如knife -> knives)
100
+        if (base.endsWith('fe') && word === base.slice(0, -2) + 'ves') {
101
+            return true;
102
+        }
103
+        
104
+        // 处理以f结尾的单词变为复数时,f变为ves的情况 (如leaf -> leaves)
105
+        if (base.endsWith('f') && word === base.slice(0, -1) + 'ves') {
106
+            return true;
107
+        }
108
+        
109
+        // 处理常规的第三人称单数形式(动词后加s或es)
110
+        if (word === base + 's' || word === base + 'es') {
111
+            return true;
112
+        }
113
+        
114
+        // 处理反向情况:如果base是word加s或es
115
+        if (base === word + 's' || base === word + 'es') {
116
+            return true;
117
+        }
118
+        
119
+        // 处理动词的过去式和过去分词
120
+        // 常规动词加-ed
121
+        if (word === base + 'ed') {
122
+            return true;
123
+        }
124
+        // 以e结尾的动词加-d
125
+        if (base.endsWith('e') && word === base + 'd') {
126
+            return true;
127
+        }
128
+        // 以辅音+y结尾的动词,y变i再加-ed
129
+        if (base.length > 1 && 
130
+            base.endsWith('y') && 
131
+            !'aeiou'.includes(base.charAt(base.length - 2)) && 
132
+            word === base.slice(0, -1) + 'ied') {
133
+            return true;
134
+        }
135
+        
136
+        // 处理动词的现在分词
137
+        // 以e结尾的动词,去e加-ing
138
+        if (base.endsWith('e') && word === base.slice(0, -1) + 'ing') {
139
+            return true;
140
+        }
141
+        // 常规动词加-ing
142
+        if (word === base + 'ing') {
143
+            return true;
144
+        }
145
+        
146
+        // 处理形容词的比较级和最高级
147
+        // 常规形容词加-er/-est
148
+        if (word === base + 'er' || word === base + 'est') {
149
+            return true;
150
+        }
151
+        // 以e结尾的形容词加-r/-st
152
+        if (base.endsWith('e') && (word === base + 'r' || word === base + 'st')) {
153
+            return true;
154
+        }
155
+        // 以辅音+y结尾的形容词,y变i再加-er/-est
156
+        if (base.length > 1 && 
157
+            base.endsWith('y') && 
158
+            !'aeiou'.includes(base.charAt(base.length - 2)) && 
159
+            (word === base.slice(0, -1) + 'ier' || word === base.slice(0, -1) + 'iest')) {
160
+            return true;
161
+        }
162
+        
163
+        // 处理副词的形成
164
+        // 常规形容词加-ly
165
+        if (word === base + 'ly') {
166
+            return true;
167
+        }
168
+        // 以y结尾的形容词,y变i加-ly
169
+        if (base.endsWith('y') && word === base.slice(0, -1) + 'ily') {
170
+            return true;
171
+        }
172
+        
173
+        // 处理反向情况
174
+        // 如果word是变形后的单词,base是基本形式
175
+        
176
+        // 过去式/过去分词 -> 基本形式
177
+        if (word.endsWith('ed') && base === word.slice(0, -2)) {
178
+            return true;
179
+        }
180
+        // 以e结尾的动词加d -> 基本形式
181
+        if (word.endsWith('d') && !word.endsWith('ed') && base === word.slice(0, -1)) {
182
+            return true;
183
+        }
184
+        // 以辅音+y结尾变为ied -> 基本形式
185
+        if (word.endsWith('ied') && base === word.slice(0, -3) + 'y') {
186
+            return true;
187
+        }
188
+        
189
+        // 现在分词 -> 基本形式
190
+        if (word.endsWith('ing')) {
191
+            // 常规情况
192
+            if (base === word.slice(0, -3)) {
193
+                return true;
194
+            }
195
+            // 以e结尾的动词去e加ing
196
+            if (base.endsWith('e') && base === word.slice(0, -3) + 'e') {
197
+                return true;
198
+            }
199
+        }
200
+        
201
+        // 比较级/最高级 -> 基本形式
202
+        if (word.endsWith('er') && base === word.slice(0, -2)) {
203
+            return true;
204
+        }
205
+        if (word.endsWith('est') && base === word.slice(0, -3)) {
206
+            return true;
207
+        }
208
+        // 以e结尾的形容词
209
+        if (word.endsWith('r') && !word.endsWith('er') && base.endsWith('e') && base === word.slice(0, -1)) {
210
+            return true;
211
+        }
212
+        if (word.endsWith('st') && !word.endsWith('est') && base.endsWith('e') && base === word.slice(0, -2)) {
213
+            return true;
214
+        }
215
+        // 以辅音+y结尾变为ier/iest
216
+        if (word.endsWith('ier') && base === word.slice(0, -3) + 'y') {
217
+            return true;
218
+        }
219
+        if (word.endsWith('iest') && base === word.slice(0, -4) + 'y') {
220
+            return true;
221
+        }
222
+        
223
+        // 副词 -> 形容词
224
+        if (word.endsWith('ly') && base === word.slice(0, -2)) {
225
+            return true;
226
+        }
227
+        // 以y结尾变为ily
228
+        if (word.endsWith('ily') && base === word.slice(0, -3) + 'y') {
229
+            return true;
230
+        }
231
+        
232
+        // 处理不规则动词过去式 (如go -> went, is -> was)
233
+        const irregularVerbs = {
234
+            'go': ['went', 'gone', 'going', 'goes'],
235
+            'be': ['am', 'is', 'are', 'was', 'were', 'been', 'being'],
236
+            'do': ['did', 'done', 'doing', 'does'],
237
+            'have': ['has', 'had', 'having'],
238
+            'say': ['said', 'saying', 'says'],
239
+            'make': ['made', 'making', 'makes'],
240
+            'get': ['got', 'gotten', 'getting', 'gets'],
241
+            'know': ['knew', 'known', 'knowing', 'knows'],
242
+            'take': ['took', 'taken', 'taking', 'takes'],
243
+            'see': ['saw', 'seen', 'seeing', 'sees'],
244
+            'come': ['came', 'coming', 'comes'],
245
+            'think': ['thought', 'thinking', 'thinks'],
246
+            'look': ['looked', 'looking', 'looks'],
247
+            'want': ['wanted', 'wanting', 'wants'],
248
+            'give': ['gave', 'given', 'giving', 'gives'],
249
+            'use': ['used', 'using', 'uses'],
250
+            'find': ['found', 'finding', 'finds'],
251
+            'tell': ['told', 'telling', 'tells'],
252
+            'ask': ['asked', 'asking', 'asks'],
253
+            'work': ['worked', 'working', 'works'],
254
+            'seem': ['seemed', 'seeming', 'seems'],
255
+            'feel': ['felt', 'feeling', 'feels'],
256
+            'try': ['tried', 'trying', 'tries'],
257
+            'leave': ['left', 'leaving', 'leaves'],
258
+            'call': ['called', 'calling', 'calls']
259
+        };
260
+        
261
+        // 检查是否是不规则动词的变形
262
+        if (irregularVerbs[base] && irregularVerbs[base].includes(word)) {
263
+            return true;
264
+        }
265
+        
266
+        if (Object.entries(irregularVerbs).some(([verb, forms]) => 
267
+            verb === word && forms.includes(base))) {
268
+            return true;
269
+        }
270
+        
271
+        return false;
272
+    }
273
+    
87 274
     // 处理用户提供的每个单词
88 275
     userWordsList.forEach(originalInput => {
89 276
         // 跳过空输入
@@ -103,6 +290,11 @@ export function enhanceFormsOfWords(jsonObj, userWords) {
103 290
             if (articleWord === originalInput) {
104 291
                 shouldAdd = true;
105 292
             } 
293
+            // 检查特殊变形规则 (提高优先级,放在前面检查)
294
+            else if (checkSpecialWordForms(articleWord, originalInput) || 
295
+                     checkSpecialWordForms(originalInput, articleWord)) {
296
+                shouldAdd = true;
297
+            }
106 298
             // 对于长度小于等于4的单词,只进行完全匹配,不做错误修正
107 299
             else if (originalInput.length <= 4) {
108 300
                 // 不做任何处理,保持shouldAdd为false

+ 6 - 2
src/api/yjbdc/yjbdcController.js

@@ -230,11 +230,9 @@ export async function GenerateArticle(ctx) {
230 230
             "提供5道针对文章阅读理解的单项选择题,各有四个选项,并提供答案;"+
231 231
             "单项选择题和选项也要有中文翻译;"+
232 232
             "必须确保用户提供的每个单词(除像'fuck'、'shit'等脏话外)至少在文章中出现一次,可以是原形或某种变形(第三人称单数、复数、过去式、过去分词、现在分词、比较级、最高级等等所有可能的变形形式)。比如用户输入'go',文章除了'go'以外,也可以生成像'goes'、'went'、'gone'、'going'等单词;"+
233
-            "用户提交的每个单词,都放入FormsOfWords中;"+
234 233
             "内容格式为JSON,必须严格按照以下格式,不能有任何字段名错误或缺失:{"+
235 234
             "  \"ArticleEnglish\":[\"<英文文章句子1>\",\"<英文文章句子2>\"...],"+
236 235
             "  \"ArticleChinese\":[\"<中文翻译句子1>\",\"<中文翻译句子2>\"...],"+
237
-            "  \"FormsOfWords\":[\"<单词1>\",\"<单词2>\",\"<单词3>\",...],"+
238 236
             "  \"Question\":[{"+
239 237
             "    \"QuestionEnglish\":\"<英语题目1>\","+
240 238
             "    \"QuestionChinese\":\"<题目1中文翻译>\","+
@@ -269,6 +267,9 @@ export async function GenerateArticle(ctx) {
269 267
             else if (params.AIVersion=="1.5"){
270 268
                 aiProvider="volces1-6";
271 269
             }
270
+            else if (params.AIVersion=="1.8"){
271
+                aiProvider="qwen-plus";
272
+            }
272 273
             
273 274
             try {
274 275
                 //开始时间
@@ -276,6 +277,9 @@ export async function GenerateArticle(ctx) {
276 277
                 // 使用aiController生成文章
277 278
                 let result2 = await aiController.generateArticle(content, aiProvider);
278 279
                 
280
+                //console.log(result2);
281
+                //debugger;
282
+
279 283
                 // 校验和修复JSON结构
280 284
                 result2 = aiController.validateAndFixJSON(result2);
281 285
                 //console.log("JSON结构已校验和修复");

+ 3 - 0
src/config/index.js

@@ -76,6 +76,9 @@ const commonConfig = {
76 76
         apikeyCJ:"d276e65d-4c39-49ad-a2e2-5060c30ca9a0",
77 77
         apikeyHLR:"2b7d737e-6773-4d55-ae77-da8d4e819c96",
78 78
     },
79
+    aliyun:{
80
+        accessKey: "sk-12e38cdfe5b1477880e5c99efbd10b48", // 需要替换为实际的阿里云AccessKey
81
+    },
79 82
     BufferMemoryTimeSuperLower:1,//缓存时间1秒
80 83
     BufferMemoryTimeLower:5,//缓存时间5秒
81 84
     BufferMemoryTimeLow:10,//缓存时间10秒

+ 148 - 0
src/test/test-enhance-words.js

@@ -0,0 +1,148 @@
1
+import { enhanceFormsOfWords } from '../api/yjbdc/enhanceFormsOfWords.js';
2
+
3
+// 测试文章
4
+const testArticle = [
5
+    "She cries when she is sad.",
6
+    "The leaves fall from the trees in autumn.",
7
+    "He went to the store yesterday.",
8
+    "The knives are in the drawer.",
9
+    "I am trying to understand this concept."
10
+];
11
+
12
+// 创建测试JSON对象
13
+const testJsonObj = {
14
+    ArticleEnglish: testArticle
15
+};
16
+
17
+// 打印测试文章
18
+console.log("[DEBUG] 文章中的句子:");
19
+testArticle.forEach((sentence, index) => {
20
+    console.log(`[DEBUG]   ${index + 1}: ${sentence}`);
21
+});
22
+
23
+// 提取文章中的所有单词
24
+const allWords = testArticle.join(" ")
25
+    .toLowerCase()
26
+    .replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, " ")
27
+    .replace(/\s+/g, " ")
28
+    .trim()
29
+    .split(" ");
30
+
31
+console.log("[DEBUG] 文章中的所有单词:");
32
+console.log(`[DEBUG]   ${allWords.join(" ")}`);
33
+
34
+// 测试checkSpecialWordForms函数
35
+console.log("测试checkSpecialWordForms函数...");
36
+
37
+// 从enhanceFormsOfWords.js中提取checkSpecialWordForms函数
38
+// 由于它是私有函数,我们需要重新实现它进行测试
39
+function checkSpecialWordForms(word, base) {
40
+    // 处理以y结尾的单词变为复数时,y变为ies的情况 (如cry -> cries)
41
+    if (base.endsWith('y') && word === base.slice(0, -1) + 'ies') {
42
+        return true;
43
+    }
44
+    
45
+    // 处理以fe结尾的单词变为复数时,fe变为ves的情况 (如knife -> knives)
46
+    if (base.endsWith('fe') && word === base.slice(0, -2) + 'ves') {
47
+        return true;
48
+    }
49
+    
50
+    // 处理以f结尾的单词变为复数时,f变为ves的情况 (如leaf -> leaves)
51
+    if (base.endsWith('f') && word === base.slice(0, -1) + 'ves') {
52
+        return true;
53
+    }
54
+    
55
+    // 处理不规则动词过去式 (如go -> went)
56
+    const irregularVerbs = {
57
+        'go': ['went', 'gone', 'going', 'goes'],
58
+        'try': ['tried', 'trying', 'tries']
59
+    };
60
+    
61
+    // 检查是否是不规则动词的变形
62
+    if (irregularVerbs[base] && irregularVerbs[base].includes(word)) {
63
+        return true;
64
+    }
65
+    
66
+    return false;
67
+}
68
+
69
+// 测试用例
70
+const testCases = [
71
+    { base: "cry", form: "cries", expected: true },
72
+    { base: "leaf", form: "leaves", expected: true },
73
+    { base: "knife", form: "knives", expected: true },
74
+    { base: "go", form: "went", expected: true },
75
+    { base: "try", form: "trying", expected: true },
76
+    { base: "cat", form: "cats", expected: false } // 这个应该返回false,因为我们的简化版本不处理常规的复数形式
77
+];
78
+
79
+// 运行测试
80
+testCases.forEach(test => {
81
+    console.log("----------------------------------------");
82
+    console.log(`测试: ${test.base} -> ${test.form}`);
83
+    const result = checkSpecialWordForms(test.form, test.base);
84
+    console.log(`结果: ${result}`);
85
+    console.log(`预期: ${test.expected}`);
86
+    if (result === test.expected) {
87
+        console.log("✅ 通过");
88
+    } else {
89
+        console.log("❌ 失败");
90
+    }
91
+});
92
+
93
+// 测试enhanceFormsOfWords函数
94
+console.log("----------------------------------------");
95
+console.log("开始测试enhanceFormsOfWords函数...");
96
+
97
+// 测试用例
98
+const enhanceTestCases = [
99
+    { input: "cry", expected: ["cry", "cries"] },
100
+    { input: "leaf", expected: ["leaf", "leaves"] },
101
+    { input: "go", expected: ["go", "went"] },
102
+    { input: "knife", expected: ["knife", "knives"] },
103
+    { input: "try", expected: ["try", "trying"] }
104
+];
105
+
106
+// 运行测试
107
+enhanceTestCases.forEach(test => {
108
+    console.log("----------------------------------------");
109
+    console.log(`[DEBUG] 处理测试输入: "${test.input}"`);
110
+    
111
+    const result = enhanceFormsOfWords({ ArticleEnglish: testArticle }, test.input);
112
+    const formsFound = result.FormsOfWords || [];
113
+    
114
+    console.log(`测试输入: "${test.input}"`);
115
+    console.log(`识别到的单词形式: [${formsFound.map(w => `"${w}"`).join("")}]`);
116
+    
117
+    // 检查是否所有预期的单词变形都被识别
118
+    const allExpectedFound = test.expected.every(word => formsFound.includes(word));
119
+    
120
+    if (allExpectedFound) {
121
+        console.log("✅ 测试通过: 所有预期的单词变形都被识别");
122
+    } else {
123
+        console.log("❌ 测试失败: 有预期的单词变形未被识别");
124
+        const missing = test.expected.filter(word => !formsFound.includes(word));
125
+        console.log(`  缺少: ${missing.join(", ")}`);
126
+    }
127
+});
128
+
129
+// 测试多个单词输入
130
+console.log("----------------------------------------");
131
+const multiWordInput = "cryleafgo";
132
+const multiWordResult = enhanceFormsOfWords({ ArticleEnglish: testArticle }, multiWordInput);
133
+const multiWordForms = multiWordResult.FormsOfWords || [];
134
+
135
+console.log(`测试多个单词输入: "${multiWordInput}"`);
136
+console.log(`识别到的单词形式: [${multiWordForms.map(w => `"${w}"`).join("")}]`);
137
+
138
+// 预期的单词变形
139
+const expectedMultiWordForms = ["cry", "leaf", "go", "cries", "leaves", "went"];
140
+const allMultiWordExpectedFound = expectedMultiWordForms.every(word => multiWordForms.includes(word));
141
+
142
+if (allMultiWordExpectedFound) {
143
+    console.log("✅ 多单词测试通过: 所有预期的单词变形都被识别");
144
+} else {
145
+    console.log("❌ 多单词测试失败: 有预期的单词变形未被识别");
146
+    const missing = expectedMultiWordForms.filter(word => !multiWordForms.includes(word));
147
+    console.log(`  缺少: ${missing.join(", ")}`);
148
+}

+ 75 - 0
src/test/test-enhanced-grammar.js

@@ -0,0 +1,75 @@
1
+import { enhanceFormsOfWords } from '../api/yjbdc/enhanceFormsOfWords.js';
2
+
3
+// 测试文章,包含各种语法变形
4
+const testArticle = [
5
+    "I walk to school every day. Yesterday, I walked to school. I am walking right now.",
6
+    "She likes to read books. She liked that novel. She is liking this new approach.",
7
+    "They try hard in class. They tried their best yesterday. They are trying to improve.",
8
+    "He makes delicious food. He is making dinner now. He made breakfast this morning.",
9
+    "The tall building is on the left. That building is taller than this one. It's the tallest in the city.",
10
+    "She is a nice person. She is nicer than her brother. She is the nicest in her family.",
11
+    "He is happy with his results. He is happier than before. He is the happiest person I know. He smiled happily.",
12
+    "She runs quick. She moves quickly. The quick brown fox jumps over the lazy dog."
13
+];
14
+
15
+// 创建测试JSON对象
16
+const testJsonObj = {
17
+    ArticleEnglish: testArticle
18
+};
19
+
20
+// 测试enhanceFormsOfWords函数对新增语法变形规则的识别能力
21
+console.log("测试enhanceFormsOfWords函数对新增语法变形规则的识别能力...");
22
+console.log("========================================");
23
+
24
+// 测试用例
25
+const testCases = [
26
+    // 动词过去式和现在分词
27
+    { input: "walk", expected: ["walk", "walked", "walking"] },
28
+    { input: "like", expected: ["like", "liked"] },
29
+    { input: "try", expected: ["try", "tried"] },
30
+    
31
+    // 重复一些测试,确保结果一致
32
+    { input: "walk", expected: ["walk", "walked", "walking"] },
33
+    { input: "make", expected: ["make", "making"] },
34
+    
35
+    // 形容词比较级和最高级
36
+    { input: "tall", expected: ["tall", "taller", "tallest"] },
37
+    { input: "nice", expected: ["nice", "nicer", "nicest"] },
38
+    { input: "happy", expected: ["happy", "happier", "happiest", "happily"] },
39
+    
40
+    // 副词
41
+    { input: "quick", expected: ["quick", "quickly"] },
42
+    
43
+    // 再次测试happy,确保结果一致
44
+    { input: "happy", expected: ["happy", "happier", "happiest", "happily"] },
45
+    
46
+    // 反向测试:从变形形式到基本形式
47
+    { input: "walked", expected: ["walked", "walk"] },
48
+    { input: "making", expected: ["making", "make"] },
49
+    { input: "taller", expected: ["taller", "tall"] },
50
+    { input: "happily", expected: ["happily", "happy"] }
51
+];
52
+
53
+// 运行测试
54
+testCases.forEach(test => {
55
+    console.log("----------------------------------------");
56
+    const result = enhanceFormsOfWords({ ArticleEnglish: testArticle }, test.input);
57
+    const formsFound = result.FormsOfWords || [];
58
+    
59
+    console.log(`测试输入: "${test.input}"`);
60
+    console.log(`识别到的单词形式: [${formsFound.map(w => `"${w}"`).join("")}]`);
61
+    
62
+    // 检查是否所有预期的单词变形都被识别
63
+    const allExpectedFound = test.expected.every(word => formsFound.includes(word));
64
+    
65
+    if (allExpectedFound) {
66
+        console.log("✅ 测试通过: 成功识别所有预期的单词变形");
67
+    } else {
68
+        console.log("❌ 测试失败: 有预期的单词变形未被识别");
69
+        const missing = test.expected.filter(word => !formsFound.includes(word));
70
+        console.log(`  缺少: ${missing.join(", ")}`);
71
+    }
72
+});
73
+
74
+console.log("========================================");
75
+console.log("测试完成");

+ 43 - 0
src/test/test-love-case.js

@@ -0,0 +1,43 @@
1
+import { enhanceFormsOfWords } from '../api/yjbdc/enhanceFormsOfWords.js';
2
+
3
+// 测试文章,包含love和loves
4
+const testArticle = [
5
+    "I love reading books.",
6
+    "She loves to dance.",
7
+    "Love is a powerful emotion.",
8
+    "They love each other very much."
9
+];
10
+
11
+// 创建测试JSON对象
12
+const testJsonObj = {
13
+    ArticleEnglish: testArticle
14
+};
15
+
16
+// 测试enhanceFormsOfWords函数识别'love'到'loves'的能力
17
+console.log("测试enhanceFormsOfWords函数识别'love'到'loves'的能力...");
18
+console.log("----------------------------------------");
19
+
20
+// 测试用例
21
+const input = "love";
22
+const result = enhanceFormsOfWords({ ArticleEnglish: testArticle }, input);
23
+const formsFound = result.FormsOfWords || [];
24
+
25
+console.log(`测试输入: "${input}"`);
26
+console.log(`识别到的单词形式: [${formsFound.map(w => `"${w}"`).join("")}]`);
27
+
28
+// 检查是否识别到'loves'
29
+const hasLoves = formsFound.includes("loves");
30
+// 检查是否保留了原始单词'love'
31
+const hasLove = formsFound.includes("love");
32
+
33
+if (hasLoves) {
34
+    console.log("✅ 测试通过: 成功识别'loves'作为'love'的变形");
35
+} else {
36
+    console.log("❌ 测试失败: 未能识别'loves'作为'love'的变形");
37
+}
38
+
39
+if (hasLove) {
40
+    console.log("✅ 测试通过: 成功保留原始单词'love'");
41
+} else {
42
+    console.log("❌ 测试失败: 未能保留原始单词'love'");
43
+}