소스 검색

修改bug

chengjie 18 시간 전
부모
커밋
475b4f106b
3개의 변경된 파일91개의 추가작업 그리고 7개의 파일을 삭제
  1. 33 2
      src/api/miaoguo/miaoguoController.js
  2. 30 5
      src/model/miaoguo.js
  3. 28 0
      test/errorRegression.test.js

+ 33 - 2
src/api/miaoguo/miaoguoController.js

@@ -4229,6 +4229,22 @@ export async function GetMiaoguoTestPackage(ctx) {
4229 4229
     ctx.body = { errcode: 10000, result };
4230 4230
 }
4231 4231
 
4232
+export function buildCambridgeCategoryUnits(wordList, testFunction) {
4233
+    const units = [];
4234
+    for (let start = 0; start < wordList.length; start += 10) {
4235
+        const words = wordList.slice(start, start + 10).map(item => item.Word);
4236
+        const id = units.length + 1;
4237
+        units.push({
4238
+            ID: id,
4239
+            UnitName: "Lesson " + id,
4240
+            ListStr: words.join("、"),
4241
+            Length: words.length,
4242
+            TestFunction: testFunction,
4243
+        });
4244
+    }
4245
+    return units;
4246
+}
4247
+
4232 4248
 export async function GetMiaoguoTestUnit(ctx) {
4233 4249
     const param = {
4234 4250
         UserID: ctx.query.UserID || 0,
@@ -4360,6 +4376,18 @@ export async function GetMiaoguoTestUnit(ctx) {
4360 4376
                     delete unit.Words;
4361 4377
                 }
4362 4378
                 arr.push(...arrTemp);
4379
+            } else if (["剑桥KET", "剑桥PET", "剑桥FCE"].includes(info[0].LibraryName1)) {
4380
+                let sourceBookID = 133;
4381
+                if (info[0].LibraryName1 == "剑桥PET")
4382
+                    sourceBookID = 134;
4383
+                else if (info[0].LibraryName1 == "剑桥FCE")
4384
+                    sourceBookID = 136;
4385
+
4386
+                result = await hanzi.GetEnglishUnitData({
4387
+                    BookID: sourceBookID,
4388
+                    LessonID: info[0].BookIDOld,
4389
+                });
4390
+                arr.push(...buildCambridgeCategoryUnits(result, info[0].TestFunction));
4363 4391
             } else {
4364 4392
                 const param2 = { BookID: info[0].BookIDOld };
4365 4393
                 result = await hanzi.GetEnglishUnitData(param2);
@@ -4774,8 +4802,11 @@ export async function GetTestEnglishWords(ctx) {
4774 4802
             param.Type = "GET6";
4775 4803
 
4776 4804
         list = await miaoguo.GetTestEnglishWords(param);
4777
-        param.Type = "textbook";
4778
-        const listTextbook = await miaoguo.GetTestEnglishWords(param);
4805
+        const listTextbook = await miaoguo.GetTestEnglishWords({
4806
+            ...param,
4807
+            Type: "textbook",
4808
+            Words: list.map(item => item.Word),
4809
+        });
4779 4810
         for (const item of list) {
4780 4811
             const json = JSON.parse(item.JSONString);
4781 4812
             item.Data = json.ENG;

+ 30 - 5
src/model/miaoguo.js

@@ -10,6 +10,25 @@ function normalizeIdList(value) {
10 10
     return ids.length > 0 ? ids.join(',') : '0';
11 11
 }
12 12
 
13
+function normalizeEnglishWordList(value) {
14
+    const list = Array.isArray(value) ? value : String(value || '').split(',');
15
+    return list
16
+        .map(item => String(item).trim().replace(/^(["'])(.*)\1$/, '$2'))
17
+        .filter(Boolean);
18
+}
19
+
20
+export function buildTextbookWordsQuery(value) {
21
+    const words = normalizeEnglishWordList(value);
22
+    if (words.length === 0)
23
+        return null;
24
+
25
+    const placeholders = words.map(() => '?').join(',');
26
+    return {
27
+        sql: `Select * from Words where BookID in (151,152,153,161,162,163,164,165,166,167,168,141,142,143,144,145,146) and Word in (${placeholders}) order by Word,BookID,ID`,
28
+        params: words,
29
+    };
30
+}
31
+
13 32
 function normalizeOrderType(orderType, fallback = 'ac.UpdateTime desc') {
14 33
     const allowList = new Set([
15 34
         'ac.UpdateTime desc',
@@ -800,11 +819,17 @@ class Miaoguo {
800 819
     }
801 820
 
802 821
     static async GetTestEnglishWords(obj) {
803
-        let sql = "select wf.ID,wf.SentenceID,ml.JSONString from WordFrequency wf inner join MiaoguoLiteracy ml on wf.Word=ml.Word where (ml.SearchType is null or ml.SearchType='ENG') and wf.Word in(" + obj.Words + ");";
804
-        if (obj.Words.substr(0, 12) == "\"A\",\"B\",\"C\",")
805
-            sql = "select ID,Word,JSONString from MiaoguoLiteracy where Word in(" + obj.Words + ");";
806
-        if (obj.Type == "textbook")
807
-            sql = "Select * from Words where BookID in (151,152,153,161,162,163,164,165,166,167,168,141,142,143,144,145,146) and Word in (" + obj.Words + ") order by Word,BookID,ID";
822
+        if (obj.Type == "textbook") {
823
+            const textbookQuery = buildTextbookWordsQuery(obj.Words);
824
+            if (!textbookQuery)
825
+                return [];
826
+            return await query(textbookQuery.sql, textbookQuery.params);
827
+        }
828
+
829
+        const words = String(obj.Words || '');
830
+        let sql = "select wf.ID,wf.SentenceID,ml.JSONString from WordFrequency wf inner join MiaoguoLiteracy ml on wf.Word=ml.Word where (ml.SearchType is null or ml.SearchType='ENG') and wf.Word in(" + words + ");";
831
+        if (words.substr(0, 12) == "\"A\",\"B\",\"C\",")
832
+            sql = "select ID,Word,JSONString from MiaoguoLiteracy where Word in(" + words + ");";
808 833
         if (obj.Type == "GaoKao")
809 834
             sql = "SELECT w.ID,w.Word,w.ExampleSentence,w.Translate,l.JSONString FROM kylx365_db.Words w left join MiaoguoLiteracy l on w.WordRemark=l.Word where w.BookID=" + obj.BookID + " and w.LessonID=" + obj.LessonID + " Group By w.ID;";
810 835
         else if (obj.Type == "GET4" || obj.Type == "GET6")

+ 28 - 0
test/errorRegression.test.js

@@ -4,6 +4,8 @@ import config from '../src/config/index.js';
4 4
 import { Decrypt, Encrypt, decryptUrlMiddle } from '../src/util/crypto/index.js';
5 5
 import { stringUtils } from '../src/util/stringClass.js';
6 6
 import { GetReaderBooksChapter, GetReaderBooksChapterContent } from '../src/api/yjbdc/readerController.js';
7
+import { buildTextbookWordsQuery } from '../src/model/miaoguo.js';
8
+import { buildCambridgeCategoryUnits } from '../src/api/miaoguo/miaoguoController.js';
7 9
 
8 10
 test('ReplaceAllString 将正则特殊字符按普通文本替换', () => {
9 11
     assert.equal(stringUtils.ReplaceAllString('a+b+c', '+', '___'), 'a___b___c');
@@ -73,3 +75,29 @@ test('阅读器正文接口校验章节号并正确换算回到过去变成猫
73 75
     assert.equal(validCtx.body.errcode, 10000);
74 76
     assert.ok(validCtx.body.result.length > 0);
75 77
 });
78
+
79
+test('教材释义查询不生成空的 IN 条件并参数化单词', () => {
80
+    assert.equal(buildTextbookWordsQuery([]), null);
81
+    assert.equal(buildTextbookWordsQuery(''), null);
82
+
83
+    const textbookQuery = buildTextbookWordsQuery(['abandon', "student's"]);
84
+    assert.deepEqual(textbookQuery.params, ['abandon', "student's"]);
85
+    assert.match(textbookQuery.sql, /Word in \(\?,\?\)/);
86
+    assert.equal(textbookQuery.sql.includes('abandon'), false);
87
+
88
+    const legacyQuery = buildTextbookWordsQuery('"ability","about"');
89
+    assert.deepEqual(legacyQuery.params, ['ability', 'about']);
90
+});
91
+
92
+test('剑桥分类词汇按每十个单词生成课程并保留尾组', () => {
93
+    const words = Array.from({ length: 23 }, (_, index) => ({ Word: 'word' + (index + 1) }));
94
+    const testFunction = [{ N: 'read' }];
95
+    const units = buildCambridgeCategoryUnits(words, testFunction);
96
+
97
+    assert.deepEqual(units.map(item => item.ID), [1, 2, 3]);
98
+    assert.deepEqual(units.map(item => item.UnitName), ['Lesson 1', 'Lesson 2', 'Lesson 3']);
99
+    assert.deepEqual(units.map(item => item.Length), [10, 10, 3]);
100
+    assert.equal(units[2].ListStr, 'word21、word22、word23');
101
+    assert.equal(units[0].TestFunction, testFunction);
102
+    assert.deepEqual(buildCambridgeCategoryUnits([], testFunction), []);
103
+});