chengjie 5 月之前
父节点
当前提交
9b129f7f9a

+ 7 - 8
.cloudbase/container/debug.json

@@ -2,18 +2,17 @@
2
 App({
2
 App({
3
   globalData: {
3
   globalData: {
4
     Version: "1.0.0",
4
     Version: "1.0.0",
5
-    IsProduction: true,
6
-    ShareTitle: "",
5
+    //IsProduction: true,
6
+    ShareTitle: "语境背单词",
7
     SharePath: "pages/index/index",
7
     SharePath: "pages/index/index",
8
     ShareImage: '../images/program_share-a01.png',
8
     ShareImage: '../images/program_share-a01.png',
9
-    ProgramID: 107,
10
-    ProgramName: "",
9
+    ProgramID: 186,
10
+    ProgramName: "语境背单词",
11
     AppID: "wx80059777521b897c",
11
     AppID: "wx80059777521b897c",
12
-    serverUrl: "https://www.kylx365.com/apiData/",
13
-    serverUrlServer: "https://www.kylx365.com/apiData/",
14
-    serverUrlLocalhost: "http://localhost:3020/apiData/",
12
+    serverUrl: "https://scoreline.kylx365.com/apiData/",
13
+    serverUrlServer: "https://scoreline.kylx365.com/apiData/",
14
+    serverUrlLocalhost: "http://localhost:3000/apiData/",
15
     audioUrlBaidu: "https://tsn.baidu.com/text2audio?lan=zh&ctp=1&cuid=abcdxxx&tok=[token]&tex=[word]&vol=9&per=0&spd=3&pit=5",
15
     audioUrlBaidu: "https://tsn.baidu.com/text2audio?lan=zh&ctp=1&cuid=abcdxxx&tok=[token]&tex=[word]&vol=9&per=0&spd=3&pit=5",
16
-    audioUrlYoudao: "https://dict.youdao.com/dictvoice?rate=10&le=auto&audio=[word]",
17
     uploadImageUrl: "https://miaguo-1253256735.file.myqcloud.com/",
16
     uploadImageUrl: "https://miaguo-1253256735.file.myqcloud.com/",
18
     officialAccounts:"https://mp.weixin.qq.com/s/gO9S4PrPl1Uu1iksyRuBgw",
17
     officialAccounts:"https://mp.weixin.qq.com/s/gO9S4PrPl1Uu1iksyRuBgw",
19
     BaiduToken: "",//百度开发平台token
18
     BaiduToken: "",//百度开发平台token

+ 2 - 1
app.json

@@ -1,12 +1,13 @@
1
 {
1
 {
2
   "pages": [
2
   "pages": [
3
+    "pages/index/index",
4
+    "pages/main/myarticles",
3
     "pages/main/article",
5
     "pages/main/article",
4
     "pages/main/index",
6
     "pages/main/index",
5
     "pages/main/paste",
7
     "pages/main/paste",
6
     "pages/main/ocr",
8
     "pages/main/ocr",
7
     "pages/main/selectword",
9
     "pages/main/selectword",
8
     "pages/main/wordsinput",
10
     "pages/main/wordsinput",
9
-    "pages/index/index",
10
     "pages/logs/logs",
11
     "pages/logs/logs",
11
     "pages/article_generator/article_generator",
12
     "pages/article_generator/article_generator",
12
     "pages/ocr/ocr"
13
     "pages/ocr/ocr"

二进制
app.wxss


二进制
pages/article_generator/article_generator.js


二进制
pages/images/pic_01.png


二进制
pages/images/pic_h01.png


二进制
pages/images/pic_h05.png


二进制
pages/images/pic_h06.png


二进制
pages/images/pic_h07.png


二进制
pages/images/pic_h08.png


二进制
pages/images/sysIcon_a01.png


二进制
pages/images/sysIcon_a14.png


+ 97 - 31
pages/images/sysIcon_b01.png


+ 0 - 11
pages/index/index.json

@@ -1,14 +1,3 @@
1
 <view class="container FlexColumn" style='min-height:{{Containnerheight}}rpx;'>
1
 <view class="container FlexColumn" style='min-height:{{Containnerheight}}rpx;'>
2
-  <view style="margin-top: 30rpx; align-self: flex-start;margin:30rpx 0 0 30rpx">输入要记忆的单词</view>
3
-  <textarea class="txtWords" value="{{Words}}" bindinput="bindinputField" ></textarea>
4
-  <button class="feature-btn" bindtap="goto" data-url="../ocr/ocr">
5
-    <view class="feature-name">拍照识别获得单词</view>
6
-  </button>
7
-  <button class="feature-btn" bindtap="getTest">
8
-    <view class="feature-name">测试使用单词</view>
9
-  </button>
10
   
2
   
11
-  <button class="footer feature-btn btn-retake" bindtap="goto" data-url="../article_generator/article_generator">
12
-      <view class="feature-name">生成文章</view>
13
-  </button>
14
 </view>
3
 </view>

+ 270 - 221
pages/index/index.wxss

@@ -21,7 +21,7 @@ Page({
21
     IsBuilding:false,
21
     IsBuilding:false,
22
     IsShowLightColor:false,
22
     IsShowLightColor:false,
23
     IsShowKeyword:true,//显示关键词
23
     IsShowKeyword:true,//显示关键词
24
-    IsShowQuestion:true,
24
+    IsShowQuestion:false,
25
     IsShowTranslate:false,
25
     IsShowTranslate:false,
26
     IsShowAnswer:false,
26
     IsShowAnswer:false,
27
     IsShowSetting:false,
27
     IsShowSetting:false,
@@ -40,160 +40,191 @@ Page({
40
       IsShowPanelHelp:!hiddenhelp,
40
       IsShowPanelHelp:!hiddenhelp,
41
     });
41
     });
42
 
42
 
43
-    that.init();
43
+    if (options.ID)
44
+      that.getArticleByID(options.ID);
45
+    else  
46
+      that.init(options);
44
     that.setTheme();
47
     that.setTheme();
45
   },
48
   },
46
-
47
-  init:function(){
49
+  getArticleByID:function(id){
48
     const that=this;
50
     const that=this;
49
-    let content={
50
-          "ArticleEnglish": [
51
-              "Once upon a time, there was a king in a beautiful kingdom.",
52
-              "A fierce dragon came and brought yellow fire to the kingdom.",
53
-              "The people in the kingdom were very afraid.",
54
-              "A brave boy and a kind - hearted girl decided to go and fight against the dragon.",
55
-              "They came to the dragon's cave and saw the dragon sleeping.",
56
-              "The boy used a big stick to wake up the dragon.",
57
-              "The dragon was angry and spat out yellow fire at them.",
58
-              "But the boy and the girl were not scared.",
59
-              "They worked together and finally defeated the dragon.",
60
-              "The king was very happy and thanked the boy and the girl."
61
-          ],
62
-          "ArticleChinese": [
63
-              "从前,在一个美丽的王国里有一位国王。",
64
-              "一条凶猛的龙来了,给王国带来了黄色的火焰。",
65
-              "王国里的人们非常害怕。",
66
-              "一个勇敢的男孩和一个善良的女孩决定去与龙战斗。",
67
-              "他们来到了龙的洞穴,看到龙正在睡觉。",
68
-              "男孩用一根大棍子把龙叫醒了。",
69
-              "龙很生气,朝他们吐出了黄色的火焰。",
70
-              "但是男孩和女孩并不害怕。",
71
-              "他们齐心协力,最终打败了龙。",
72
-              "国王非常高兴,感谢了男孩和女孩。"
73
-          ],
74
-          "FormsOfWords": [
75
-              "boy",
76
-              "girl",
77
-              "king",
78
-              "come",
79
-              "came",
80
-              "go",
81
-              "went",
82
-              "yellow",
83
-              "dragon",
84
-              "dragons",
85
-              "fire"
86
-          ],
87
-          "Question": [
88
-              {
89
-                  "QuestionEnglish": "Who brought yellow fire to the kingdom?",
90
-                  "QuestionChinese": "谁给王国带来了黄色的火焰?",
91
-                  "OptionsEnglish": [
92
-                      "A. The boy",
93
-                      "B. The girl",
94
-                      "C. The king",
95
-                      //"D. The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon"
96
-                      "D. The dragon"
97
-                  ],
98
-                  "OptionsChinese": [
99
-                      "A. 男孩",
100
-                      "B. 女孩",
101
-                      "C. 国王",
102
-                      "D. 龙"
103
-                  ],
104
-                  "Answer": "D"
105
-              },
106
-              {
107
-                  "QuestionEnglish": "What did the boy and the girl decide to do?",
108
-                  "QuestionChinese": "男孩和女孩决定做什么?",
109
-                  "OptionsEnglish": [
110
-                      "A. Go home",
111
-                      "B. Fight against the dragon",
112
-                      "C. Play with the dragon",
113
-                      "D. Sleep in the cave"
114
-                  ],
115
-                  "OptionsChinese": [
116
-                      "A. 回家",
117
-                      "B. 与龙战斗",
118
-                      "C. 和龙一起玩",
119
-                      "D. 在洞穴里睡觉"
120
-                  ],
121
-                  "Answer": "B"
122
-              },
123
-              {
124
-                  "QuestionEnglish": "How did the boy wake up the dragon?",
125
-                  "QuestionChinese": "男孩是如何叫醒龙的?",
126
-                  "OptionsEnglish": [
127
-                      "A. By shouting",
128
-                      "B. By using a big stick",
129
-                      "C. By throwing stones",
130
-                      "D. By singing"
131
-                  ],
132
-                  "OptionsChinese": [
133
-                      "A. 通过大喊",
134
-                      "B. 通过使用一根大棍子",
135
-                      "C. 通过扔石头",
136
-                      "D. 通过唱歌"
137
-                  ],
138
-                  "Answer": "B"
139
-              },
140
-              {
141
-                  "QuestionEnglish": "How did the dragon feel when it woke up?",
142
-                  "QuestionChinese": "龙醒来时感觉如何?",
143
-                  "OptionsEnglish": [
144
-                      "A. Happy",
145
-                      "B. Sad",
146
-                      "C. Angry",
147
-                      "D. Tired"
148
-                  ],
149
-                  "OptionsChinese": [
150
-                      "A. 高兴的",
151
-                      "B. 悲伤的",
152
-                      "C. 生气的",
153
-                      "D. 疲惫的"
154
-                  ],
155
-                  "Answer": "C"
156
-              },
157
-              {
158
-                  "QuestionEnglish": "What did the king do after the boy and the girl defeated the dragon?",
159
-                  "QuestionChinese": "男孩和女孩打败龙后,国王做了什么?",
160
-                  "OptionsEnglish": [
161
-                      "A. He punished them",
162
-                      "B. He thanked them",
163
-                      "C. He ignored them",
164
-                      "D. He was angry with them"
165
-                  ],
166
-                  "OptionsChinese": [
167
-                      "A. 他惩罚了他们",
168
-                      "B. 他感谢了他们",
169
-                      "C. 他无视了他们",
170
-                      "D. 他对他们很生气"
171
-                  ],
172
-                  "Answer": "B"
173
-              }
174
-          ]
175
-      };
176
-    that.updateData(content);
51
+    main.getData('GetYJBDCArticleList?UserID=' + app.globalData.userInfo.UserID+'&ID='+id, function (data) {
52
+      if (data) {
53
+        data=data[0];
54
+        that.setData({
55
+          Words:data.Words,
56
+          ID:id,
57
+        });
58
+        let content=data.JSONString;
59
+        that.updateData(content);
60
+      }
61
+    });
177
   },
62
   },
178
-  setTheme:function(){
63
+  init:function(options){
179
     const that=this;
64
     const that=this;
180
-    const css=Theme[that.data.IsShowLightColor?1:0];
181
-    wx.setNavigationBarColor({
182
-      frontColor: css.frontColor,
183
-      backgroundColor: css.backgroundColor,
184
-    });
185
-    wx.setBackgroundColor({
186
-      backgroundColor: css.backgroundColor,
187
-      backgroundColorTop:css.backgroundColor,
188
-      backgroundColorBottom:css.backgroundColor,
65
+    wx.showLoading({
66
+      title: '生成中',
189
     });
67
     });
190
     that.setData({
68
     that.setData({
191
-      ThemeCSS:css.Name,
69
+      IsBuilding:true
192
     });
70
     });
71
+    let words=app.globalData.SelectedWords.join(",");
72
+    main.postData('GenerateArticle?UserID='+app.globalData.userInfo.UserID, {
73
+      Words:words,
74
+      Level:options.Level,
75
+      ArticleStyle:options.ArticleStyle
76
+    }, function (data) {
77
+      if (data){
78
+        wx.hideLoading();
79
+        let content=data;
80
+        that.updateData(content);
81
+        that.setData({
82
+          IsBuilding:false,
83
+        });
84
+      }
85
+    });
86
+
87
+    if (1==0){
88
+    //   let content={
89
+    //     "ArticleEnglish": [
90
+    //         "Once upon a time, there was a king in a beautiful kingdom.",
91
+    //         "A fierce dragon came and brought yellow fire to the kingdom.",
92
+    //         "The people in the kingdom were very afraid.",
93
+    //         "A brave boy and a kind - hearted girl decided to go and fight against the dragon.",
94
+    //         "They came to the dragon's cave and saw the dragon sleeping.",
95
+    //         "The boy used a big stick to wake up the dragon.",
96
+    //         "The dragon was angry and spat out yellow fire at them.",
97
+    //         "But the boy and the girl were not scared.",
98
+    //         "They worked together and finally defeated the dragon.",
99
+    //         "The king was very happy and thanked the boy and the girl."
100
+    //     ],
101
+    //     "ArticleChinese": [
102
+    //         "从前,在一个美丽的王国里有一位国王。",
103
+    //         "一条凶猛的龙来了,给王国带来了黄色的火焰。",
104
+    //         "王国里的人们非常害怕。",
105
+    //         "一个勇敢的男孩和一个善良的女孩决定去与龙战斗。",
106
+    //         "他们来到了龙的洞穴,看到龙正在睡觉。",
107
+    //         "男孩用一根大棍子把龙叫醒了。",
108
+    //         "龙很生气,朝他们吐出了黄色的火焰。",
109
+    //         "但是男孩和女孩并不害怕。",
110
+    //         "他们齐心协力,最终打败了龙。",
111
+    //         "国王非常高兴,感谢了男孩和女孩。"
112
+    //     ],
113
+    //     "FormsOfWords": [
114
+    //         "boy",
115
+    //         "girl",
116
+    //         "king",
117
+    //         "come",
118
+    //         "came",
119
+    //         "go",
120
+    //         "went",
121
+    //         "yellow",
122
+    //         "dragon",
123
+    //         "dragons",
124
+    //         "fire"
125
+    //     ],
126
+    //     "Question": [
127
+    //         {
128
+    //             "QuestionEnglish": "Who brought yellow fire to the kingdom?",
129
+    //             "QuestionChinese": "谁给王国带来了黄色的火焰?",
130
+    //             "OptionsEnglish": [
131
+    //                 "A. The boy",
132
+    //                 "B. The girl",
133
+    //                 "C. The king",
134
+    //                 //"D. The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon  The dragon"
135
+    //                 "D. The dragon"
136
+    //             ],
137
+    //             "OptionsChinese": [
138
+    //                 "A. 男孩",
139
+    //                 "B. 女孩",
140
+    //                 "C. 国王",
141
+    //                 "D. 龙"
142
+    //             ],
143
+    //             "Answer": "D"
144
+    //         },
145
+    //         {
146
+    //             "QuestionEnglish": "What did the boy and the girl decide to do?",
147
+    //             "QuestionChinese": "男孩和女孩决定做什么?",
148
+    //             "OptionsEnglish": [
149
+    //                 "A. Go home",
150
+    //                 "B. Fight against the dragon",
151
+    //                 "C. Play with the dragon",
152
+    //                 "D. Sleep in the cave"
153
+    //             ],
154
+    //             "OptionsChinese": [
155
+    //                 "A. 回家",
156
+    //                 "B. 与龙战斗",
157
+    //                 "C. 和龙一起玩",
158
+    //                 "D. 在洞穴里睡觉"
159
+    //             ],
160
+    //             "Answer": "B"
161
+    //         },
162
+    //         {
163
+    //             "QuestionEnglish": "How did the boy wake up the dragon?",
164
+    //             "QuestionChinese": "男孩是如何叫醒龙的?",
165
+    //             "OptionsEnglish": [
166
+    //                 "A. By shouting",
167
+    //                 "B. By using a big stick",
168
+    //                 "C. By throwing stones",
169
+    //                 "D. By singing"
170
+    //             ],
171
+    //             "OptionsChinese": [
172
+    //                 "A. 通过大喊",
173
+    //                 "B. 通过使用一根大棍子",
174
+    //                 "C. 通过扔石头",
175
+    //                 "D. 通过唱歌"
176
+    //             ],
177
+    //             "Answer": "B"
178
+    //         },
179
+    //         {
180
+    //             "QuestionEnglish": "How did the dragon feel when it woke up?",
181
+    //             "QuestionChinese": "龙醒来时感觉如何?",
182
+    //             "OptionsEnglish": [
183
+    //                 "A. Happy",
184
+    //                 "B. Sad",
185
+    //                 "C. Angry",
186
+    //                 "D. Tired"
187
+    //             ],
188
+    //             "OptionsChinese": [
189
+    //                 "A. 高兴的",
190
+    //                 "B. 悲伤的",
191
+    //                 "C. 生气的",
192
+    //                 "D. 疲惫的"
193
+    //             ],
194
+    //             "Answer": "C"
195
+    //         },
196
+    //         {
197
+    //             "QuestionEnglish": "What did the king do after the boy and the girl defeated the dragon?",
198
+    //             "QuestionChinese": "男孩和女孩打败龙后,国王做了什么?",
199
+    //             "OptionsEnglish": [
200
+    //                 "A. He punished them",
201
+    //                 "B. He thanked them",
202
+    //                 "C. He ignored them",
203
+    //                 "D. He was angry with them"
204
+    //             ],
205
+    //             "OptionsChinese": [
206
+    //                 "A. 他惩罚了他们",
207
+    //                 "B. 他感谢了他们",
208
+    //                 "C. 他无视了他们",
209
+    //                 "D. 他对他们很生气"
210
+    //             ],
211
+    //             "Answer": "B"
212
+    //         }
213
+    //     ]
214
+    // };
215
+      that.updateData(content);
216
+    }
193
   },
217
   },
218
+  
194
   updateData:function(content){
219
   updateData:function(content){
195
     const that=this;
220
     const that=this;
196
     //console.log(content);
221
     //console.log(content);
222
+    if (typeof content === 'string') {
223
+      content = JSON.parse(content);
224
+    }
225
+    if (typeof content === 'string') {
226
+      content = JSON.parse(content);
227
+    }
197
     for(let i=0;i<content.ArticleEnglish.length;i++){
228
     for(let i=0;i<content.ArticleEnglish.length;i++){
198
       for(let j=0;j<content.FormsOfWords.length;j++){
229
       for(let j=0;j<content.FormsOfWords.length;j++){
199
         let word = content.FormsOfWords[j];
230
         let word = content.FormsOfWords[j];
@@ -220,14 +251,22 @@ Page({
220
     }
251
     }
221
     that.setData({
252
     that.setData({
222
       Content:content,
253
       Content:content,
223
-    }, function() {
224
-      // 数据加载完成后,计算swiper高度
225
-      that.calculateSwiperHeight();
226
-      setTimeout(function(){
227
-        that.setData({
228
-          IsShowQuestion:false,
229
-        })
230
-      },1000);
254
+    });
255
+  },
256
+  setTheme:function(){
257
+    const that=this;
258
+    const css=Theme[that.data.IsShowLightColor?1:0];
259
+    wx.setNavigationBarColor({
260
+      frontColor: css.frontColor,
261
+      backgroundColor: css.backgroundColor,
262
+    });
263
+    wx.setBackgroundColor({
264
+      backgroundColor: css.backgroundColor,
265
+      backgroundColorTop:css.backgroundColor,
266
+      backgroundColorBottom:css.backgroundColor,
267
+    });
268
+    that.setData({
269
+      ThemeCSS:css.Name,
231
     });
270
     });
232
   },
271
   },
233
   closeHelp:function(){
272
   closeHelp:function(){
@@ -258,16 +297,6 @@ Page({
258
     else if (name=="IsShowLightColor"){
297
     else if (name=="IsShowLightColor"){
259
       that.setTheme();
298
       that.setTheme();
260
     }
299
     }
261
-    else if (this.data[name] && (name=="IsShowTranslate" || name=="IsShowQuestion")){
262
-      wx.showLoading({
263
-        title: '请稍等',
264
-        mask:true,
265
-      })
266
-      that.calculateSwiperHeight();
267
-      setTimeout(function(){
268
-        wx.hideLoading();
269
-      },500);
270
-    }
271
   },
300
   },
272
   setShowKeyword:function(){
301
   setShowKeyword:function(){
273
     const that=this;
302
     const that=this;
@@ -301,66 +330,6 @@ Page({
301
       CurrentQuestionIndex:e.detail.current,
330
       CurrentQuestionIndex:e.detail.current,
302
     });
331
     });
303
   },
332
   },
304
-  // 计算所有swiper-item的高度,并设置swiper的高度为最高的那个
305
-  calculateSwiperHeight: function() {
306
-    const that = this;
307
-
308
-    // 增加延迟时间,确保DOM完全渲染
309
-    setTimeout(function() {
310
-      // 分别计算每个问题和选项的高度
311
-      const query = wx.createSelectorQuery();
312
-      
313
-      // 先计算问题文本的高度
314
-      query.selectAll('.text04').boundingClientRect();
315
-      
316
-      // 再计算所有选项的高度
317
-      query.selectAll('.text05').boundingClientRect();
318
-      
319
-      query.exec(function(res) {
320
-        if (!res || res.length < 2 || !res[0] || !res[1]) return;
321
-        
322
-        const questionRects = res[0];
323
-        const optionsRects = res[1];
324
-        
325
-        // 计算每个swiper-item的总高度
326
-        let itemHeights = [];
327
-        
328
-        // 假设问题和选项是一一对应的
329
-        const questionCount =questionRects.length;
330
-        
331
-        for (let i = 0; i < questionCount; i++) {
332
-          // 问题高度 + 选项高度 + 固定间距(margin等)
333
-          let totalHeight = questionRects[i].height + 100; // 100是估计的间距
334
-          for(let j=0;j<4;j++){
335
-            optionsRects[i*4+j].height=optionsRects[i*4+j].height*2+40;
336
-            console.log(optionsRects[i*4+j].height);
337
-            totalHeight+=optionsRects[i*4+j].height;
338
-          }
339
-          //debugger;
340
-          itemHeights.push(totalHeight);
341
-        }
342
-        
343
-        // 找出最高的高度
344
-        let maxHeight = 0;
345
-        itemHeights.forEach(function(height) {
346
-          if (height > maxHeight) {
347
-            maxHeight = height;
348
-          }
349
-        });
350
-        
351
-          console.log("计算的各项高度:", itemHeights);
352
-          console.log("最大高度:", maxHeight);
353
-        
354
-        // 为swiper高度增加一些额外空间(为指示点和边距)
355
-        maxHeight += 200; // 增加额外空间,确保内容完全显示
356
-        
357
-        // 设置swiper的高度
358
-        that.setData({
359
-          swiperHeight: maxHeight + 'rpx',
360
-        });
361
-      });
362
-    }, 500); // 增加延迟时间到500ms
363
-  },
364
 
333
 
365
   onContainerTap: function() {
334
   onContainerTap: function() {
366
     const currentTime = new Date().getTime();
335
     const currentTime = new Date().getTime();
@@ -379,6 +348,86 @@ Page({
379
     this.setData({
348
     this.setData({
380
       lastTapTime: currentTime
349
       lastTapTime: currentTime
381
     });
350
     });
351
+  },
352
+    //生成PDF文件
353
+  //访问服务器的GeneratePDF接口,提交this.data.Content数据,获得一个生成好的pdf文件,服务端的代码已经生成好
354
+  generatePDF: function(e) {
355
+    let that = this;
356
+    this.setData({ 
357
+      generatingPDF: true,
358
+    });
359
+    
360
+    let url = common.Encrypt("GeneratePDF");
361
+    url = "https://www.kylx365.com/apiData/" + url;
362
+    //url="http://localhost:3020/api/GeneratePDF";
363
+    wx.request({
364
+      url: url,
365
+      method: "POST",
366
+      data: {
367
+        Content: that.data.Content
368
+      },
369
+      responseType: 'arraybuffer',  // 确保响应类型为arraybuffer
370
+      success: function(res) {
371
+        // 将arraybuffer转为临时文件
372
+        const fsm = wx.getFileSystemManager();
373
+        const tempFilePath = `${wx.env.USER_DATA_PATH}/temp_${Date.now()}.pdf`;
374
+        
375
+        try {
376
+          fsm.writeFileSync(
377
+            tempFilePath,
378
+            res.data,
379
+            'binary'
380
+          );
381
+
382
+          // 直接使用临时文件路径,不再尝试永久保存
383
+          console.log('文件已生成:', tempFilePath);
384
+          
385
+          // 打开PDF文件预览
386
+          wx.openDocument({
387
+            filePath: tempFilePath,
388
+            fileType: 'pdf',
389
+            showMenu: true,  // 显示右上角菜单,可以分享
390
+            success: function() {
391
+              console.log('打开文档成功');
392
+              wx.showToast({
393
+                title: 'PDF生成成功',
394
+                icon: 'success'
395
+              });
396
+            },
397
+            fail: function(error) {
398
+              console.error('打开文档失败:', error);
399
+              wx.showToast({
400
+                title: '打开文件失败',
401
+                icon: 'none'
402
+              });
403
+            }
404
+          });
405
+        } catch (error) {
406
+          console.error('写入文件失败:', error);
407
+          wx.showToast({
408
+            title: '写入文件失败',
409
+            icon: 'none'
410
+          });
411
+        }
412
+      },
413
+      fail: function(err) {
414
+        console.error('请求GeneratePDF接口失败:', err);
415
+        wx.showToast({
416
+          title: '网络错误,请稍候重试',
417
+          icon: 'none'
418
+        });
419
+      },
420
+      complete: function() {
421
+        that.setData({ generatingPDF: false });
422
+      }
423
+    });
424
+  },
425
+  onUnload:function(){
426
+    if (!this.data.ID){
427
+      wx.navigateBack({
428
+        delta: 2,
429
+      });
430
+    }
382
   },
431
   },
383
   onShareAppMessage: function () {
432
   onShareAppMessage: function () {
384
     return {
433
     return {

+ 3 - 4
pages/main/article.json

@@ -29,9 +29,9 @@
29
   <!-- 看问题 -->
29
   <!-- 看问题 -->
30
   <view hidden="{{!IsShowQuestion}}" class="{{ThemeCSS}} panelAnswer FlexColumn">
30
   <view hidden="{{!IsShowQuestion}}" class="{{ThemeCSS}} panelAnswer FlexColumn">
31
     <view class="text03">Reading Comprehension Questions</view>
31
     <view class="text03">Reading Comprehension Questions</view>
32
-    <swiper class="panelAnswer1" style="height:{{swiperHeight}};" indicator-dots="true" current="{{CurrentQuestionIndex}}" bindchange="updateQuestionIndex" >
32
+    <swiper class="panelAnswer1" indicator-dots="true" current="{{CurrentQuestionIndex}}" bindchange="updateQuestionIndex" >
33
       <swiper-item class="panelAnswer1Item" wx:for="{{Content.Question}}" wx:key="index" data-index="{{index}}">
33
       <swiper-item class="panelAnswer1Item" wx:for="{{Content.Question}}" wx:key="index" data-index="{{index}}">
34
-        <view class="panelAnswer1Item1 FlexColumn">
34
+        <scroll-view scroll-y="true" class="panelAnswer1Item1 FlexColumn">
35
           <view class="panelAnswer2 FlexRow">
35
           <view class="panelAnswer2 FlexRow">
36
             <image src="../images/sysIcon_c0{{index+1}}.png" wx:if="{{ThemeCSS=='DarkColor'}}" class="sysIcon_c01"></image>
36
             <image src="../images/sysIcon_c0{{index+1}}.png" wx:if="{{ThemeCSS=='DarkColor'}}" class="sysIcon_c01"></image>
37
             <image src="../images/sysIcon_d0{{index+1}}.png" wx:if="{{ThemeCSS=='LightColor'}}" class="sysIcon_c01"></image>
37
             <image src="../images/sysIcon_d0{{index+1}}.png" wx:if="{{ThemeCSS=='LightColor'}}" class="sysIcon_c01"></image>
@@ -39,7 +39,6 @@
39
               <view class="text041">{{item.QuestionEnglish}}</view>
39
               <view class="text041">{{item.QuestionEnglish}}</view>
40
               <view class="text042" wx:if="{{IsShowTranslate}}">{{item.QuestionChinese}}</view>
40
               <view class="text042" wx:if="{{IsShowTranslate}}">{{item.QuestionChinese}}</view>
41
             </view>
41
             </view>
42
-            
43
           </view>
42
           </view>
44
           <view class="panelAnswer3 FlexColumn" >
43
           <view class="panelAnswer3 FlexColumn" >
45
             <view class="panelAnswer31 {{ item.AnswerNumber==indexChild && IsShowAnswer?'panelAnswer310':'' }} FlexRow" wx:for="{{item.OptionsEnglish}}" wx:key="indexChild" wx:for-item="itemChild" wx:for-index="indexChild" catch:tap="selectedAnswer" data-question="{{index}}" data-index="{{indexChild}}">
44
             <view class="panelAnswer31 {{ item.AnswerNumber==indexChild && IsShowAnswer?'panelAnswer310':'' }} FlexRow" wx:for="{{item.OptionsEnglish}}" wx:key="indexChild" wx:for-item="itemChild" wx:for-index="indexChild" catch:tap="selectedAnswer" data-question="{{index}}" data-index="{{indexChild}}">
@@ -54,7 +53,7 @@
54
             </view>
53
             </view>
55
             </view>
54
             </view>
56
           </view>
55
           </view>
57
-        </view>
56
+        </scroll-view>
58
       </swiper-item>
57
       </swiper-item>
59
     </swiper>    
58
     </swiper>    
60
     <view class="panelLine2"></view>
59
     <view class="panelLine2"></view>

+ 6 - 1
pages/main/article.wxss

@@ -280,7 +280,7 @@
280
 
280
 
281
 .panelAnswer1{
281
 .panelAnswer1{
282
   width: 100%;
282
   width: 100%;
283
-  min-height: 526rpx;
283
+  height:630rpx;
284
 }
284
 }
285
 
285
 
286
 .DarkColor .panelAnswer1{
286
 .DarkColor .panelAnswer1{
@@ -294,6 +294,10 @@
294
   margin-top: 20rpx;
294
   margin-top: 20rpx;
295
   width: 750rpx;
295
   width: 750rpx;
296
 }
296
 }
297
+.panelAnswer1Item1{
298
+  width: 750rpx;
299
+  height:580rpx;
300
+}
297
 .DarkColor .panelAnswer1Item1{
301
 .DarkColor .panelAnswer1Item1{
298
   background-color: #1e1e1e;
302
   background-color: #1e1e1e;
299
 }
303
 }
@@ -332,6 +336,7 @@
332
 .panelAnswer3{
336
 .panelAnswer3{
333
   width:100%;
337
   width:100%;
334
   margin-top: 40rpx;
338
   margin-top: 40rpx;
339
+  margin-bottom: 60rpx;
335
 }
340
 }
336
 .panelAnswer31{
341
 .panelAnswer31{
337
   width:100%;
342
   width:100%;

+ 1 - 1
pages/main/index.js

@@ -8,7 +8,7 @@
8
       <view class="btn01 FlexColumn" bind:tap="goto" data-url="wordsinput">
8
       <view class="btn01 FlexColumn" bind:tap="goto" data-url="wordsinput">
9
         <view>制作</view>
9
         <view>制作</view>
10
       </view>
10
       </view>
11
-      <view class="btn02 FlexColumn">
11
+      <view class="btn02 FlexColumn" bind:tap="goto" data-url="myarticles">
12
         <view>我的文库</view>
12
         <view>我的文库</view>
13
       </view>
13
       </view>
14
     </view>
14
     </view>

+ 74 - 0
pages/main/index.wxss

@@ -0,0 +1,74 @@
1
+import common from '../../utils/util';
2
+import main from '../../utils/main';
3
+
4
+const app = getApp();
5
+
6
+Page({
7
+  data: {
8
+  },
9
+  onLoad: function (options) {
10
+    let that = this;
11
+    that.setData({
12
+      Containnerheight: main.getWindowHeight(),
13
+    });
14
+    that.getData();
15
+  },
16
+  getData:function(){
17
+    const that=this;
18
+    main.getData('GetYJBDCArticleList?UserID=' + app.globalData.userInfo.UserID, function (data) {
19
+      if (data) {
20
+        for(let i=0;i<data.length;i++){
21
+            let item=data[i];
22
+            item.WordsStr=item.Words.split(",").join(" ");
23
+        }
24
+        that.setData({
25
+          List:data,
26
+        });
27
+      }
28
+    });
29
+  },
30
+  goto: function (e) {
31
+    let that=this;
32
+    var url=e.currentTarget.dataset.url;
33
+    wx.navigateTo({
34
+      url: url,
35
+    });
36
+  },
37
+  setClipboard:function(e){
38
+    wx.setClipboardData({
39
+      data: e.currentTarget.dataset.words,
40
+      success (res) {
41
+        wx.getClipboardData({
42
+          success (res) {
43
+            app.globalData.SelectedWords=res.data.split(",");
44
+          }
45
+        });
46
+      }
47
+    });
48
+  },
49
+  deleteArticle:function(e){
50
+    const that=this;
51
+    const id=e.currentTarget.dataset.id;
52
+    wx.showModal({
53
+      title: '删除',
54
+      content: '确认删除这篇文章吗?',
55
+      complete: (res) => {
56
+        if (res.confirm) {
57
+          main.getData('DeleteYJBDCArticleList?UserID=' + app.globalData.userInfo.UserID+"&ID="+id, function (data) {
58
+             wx.showToast({
59
+               title: '删除完成',
60
+             });
61
+             that.getData();
62
+          });
63
+        }
64
+      }
65
+    });
66
+  },
67
+  onShareAppMessage: function () {
68
+    return {
69
+      title: app.globalData.ShareTitle,
70
+      path: app.globalData.SharePath + '?UserID=' + app.globalData.userInfo.UserID,
71
+      imageUrl: app.globalData.ShareImage,
72
+    }
73
+  },
74
+})

+ 4 - 0
pages/main/myarticles.json

@@ -0,0 +1,4 @@
1
+{
2
+  "navigationBarTitleText": "我的文库",
3
+  "usingComponents": {}
4
+}

+ 31 - 0
pages/main/myarticles.wxml

@@ -0,0 +1,31 @@
1
+<view class="container FlexColumn" style='min-height:{{Containnerheight}}rpx;'>
2
+  <view style="height: 50rpx;"></view>
3
+  <view class="panelNull FlexColumn" wx:if="{{List.length==0}}">
4
+    <view>无内容</view>
5
+    <view class="textNull1">请先前往首页制作短文</view>
6
+  </view>
7
+  <block wx:if="{{List.length>0}}">
8
+    <view class="panel1 FlexColumn" wx:for="{{List}}" wx:key="index">
9
+      <view class="text01" bind:tap="goto" data-url="article?ID={{item.ID}}">{{item.CreateTime}}</view>
10
+      <view class="panel11 FlexRow" bind:tap="goto" data-url="article?ID={{item.ID}}">
11
+        <view class="panelLine"></view>
12
+        <view class="panel111 FlexColumn">
13
+          <view class="text02">{{item.LevelStr}} {{item.ArticleStyle}}</view>
14
+          <view class="text03">{{item.ArticleStart}}</view>
15
+        </view>
16
+      </view>
17
+      <view class="panel12 FlexRow" bind:tap="goto" data-url="article?ID={{item.ID}}">
18
+        <text class="text04">{{item.WordsStr}}</text>
19
+      </view>
20
+
21
+      <view class="panelBtn FlexRow">
22
+        <view class="btn1" bind:tap="setClipboard" data-words="{{item.Words}}">复用单词</view>
23
+        <image src="../images/sysIcon_a13.png" class="sysIcon_a13"></image>
24
+        <view class="btn2 FlexRow" bind:tap="deleteArticle" data-id="{{item.ID}}">
25
+          <image src="../images/sysIcon_a14.png" class="sysIcon_a14"></image>
26
+        </view>
27
+      </view>
28
+    </view>
29
+  </block>
30
+  <view style="height: 100rpx;"></view>
31
+</view>

+ 90 - 0
pages/main/myarticles.wxss

@@ -0,0 +1,90 @@
1
+.panelNull{
2
+  margin-top: 410rpx;
3
+  font-size: 28rpx;
4
+  color: #C1E1C1;
5
+}
6
+.textNull1{
7
+  font-weight: 400;
8
+  font-size: 24rpx;
9
+  margin-top: 10rpx;
10
+}
11
+.panel1{
12
+  width:710rpx;
13
+  background: #1E1E1E;
14
+  border-radius: 20rpx;
15
+  margin-bottom: 20rpx;
16
+  color: #C1E1C1;
17
+  position: relative;
18
+}
19
+.text01{
20
+  align-self: start;
21
+  margin: 30rpx 0 0 30rpx;
22
+  font-size: 24rpx;
23
+}
24
+.panel11{
25
+  width: 100%;
26
+  justify-content: flex-start;
27
+  margin: 30rpx 0;
28
+}
29
+.panelLine{
30
+  width: 5rpx;
31
+  height: 83rpx;
32
+  background-color: #C1E1C1;
33
+  margin: 0 25rpx 0 30rpx;
34
+}
35
+.panel111{
36
+  align-items: flex-start;
37
+}
38
+.text02{
39
+  font-weight: 400;
40
+  font-size: 24rpx;
41
+}
42
+.text03{
43
+  font-size: 36rpx;
44
+  white-space: nowrap;
45
+  width:620rpx;
46
+  overflow-x: hidden;
47
+}
48
+.panel12{
49
+  width: 670rpx;
50
+  height:90rpx;
51
+  background: #002F24;
52
+  border-radius: 10rpx;
53
+  margin: 0 0 20rpx 0;
54
+}
55
+.text04{
56
+  font-weight: 400;
57
+  font-size: 28rpx;
58
+  width: 610rpx;
59
+  margin: 20rpx 0;
60
+}
61
+
62
+.panelBtn{
63
+  border-radius: 10rpx;
64
+  background-color: #002F24;
65
+  position: absolute;
66
+  top:20rpx;
67
+  right:20rpx;
68
+}
69
+.btn1{
70
+  width:154rpx;
71
+  line-height:53rpx;
72
+  font-size: 24rpx;
73
+  color: #FFFFFF;
74
+  text-align: center;
75
+}
76
+
77
+.btn2{
78
+  width:90rpx;
79
+  height:53rpx;
80
+}
81
+
82
+.sysIcon_a13{
83
+  width: 2rpx;
84
+  height:14rpx;
85
+}
86
+
87
+.sysIcon_a14{
88
+  width: 20rpx;
89
+  height:22rpx;
90
+}

+ 7 - 0
pages/main/ocr.js

@@ -44,8 +44,15 @@ Page({
44
       }
44
       }
45
     });
45
     });
46
   },
46
   },
47
+  bindKeyInput:function(e){
48
+    let words=e.detail.value;
49
+    this.setData({
50
+      Words:words, 
51
+    });
52
+  },
47
   submit:function(){
53
   submit:function(){
48
     app.globalData.SelectedWords=this.data.Words.split("\n");
54
     app.globalData.SelectedWords=this.data.Words.split("\n");
55
+    app.globalData.SelectedWords=common.removeDuplicateAndTrimStrings(app.globalData.SelectedWords);
49
     wx.navigateBack({
56
     wx.navigateBack({
50
       delta: 1
57
       delta: 1
51
     });
58
     });

+ 1 - 1
pages/main/paste.json

@@ -12,7 +12,7 @@
12
       <view class="panel211 FlexColumn">
12
       <view class="panel211 FlexColumn">
13
         <view class="text03" wx:for="{{[1,2,3,4,5,6,7,8,9,10]}}" wx:key="index">{{item}}</view>
13
         <view class="text03" wx:for="{{[1,2,3,4,5,6,7,8,9,10]}}" wx:key="index">{{item}}</view>
14
       </view>
14
       </view>
15
-      <textarea class="text04" focus="true" value="{{Words}}" />
15
+      <textarea class="text04" focus="true" value="{{Words}}" bindinput="bindKeyInput" />
16
     </view>
16
     </view>
17
   </view>
17
   </view>
18
 
18
 

+ 30 - 11
pages/main/paste.wxss

@@ -15,16 +15,16 @@ Page({
15
     let grade=wx.getStorageSync('Grade');
15
     let grade=wx.getStorageSync('Grade');
16
     if (!grade)
16
     if (!grade)
17
       grade=[{Name:"小学",CSS:"Selected"},{Name:"初中",CSS:""},{Name:"高中",CSS:""},{Name:"大学",CSS:""}];
17
       grade=[{Name:"小学",CSS:"Selected"},{Name:"初中",CSS:""},{Name:"高中",CSS:""},{Name:"大学",CSS:""}];
18
-    let articleCategory=wx.getStorageSync('ArticleCategory');
19
-    if (!articleCategory)
20
-      articleCategory=[{Name:"任意",CSS:"Selected"},{Name:"童话",CSS:""},{Name:"科幻",CSS:""},{Name:"奇幻",CSS:""},{Name:"旅行",CSS:""},{Name:"动物",CSS:""},{Name:"家庭亲子",CSS:""},{Name:"校园生活",CSS:""},{Name:"科普",CSS:""},{Name:"节日文化",CSS:""},{Name:"成长",CSS:""},{Name:"人励志",CSS:""},{Name:"环保",CSS:""}];
18
+    let ArticleStyle=wx.getStorageSync('ArticleStyle');
19
+    if (!ArticleStyle)
20
+      ArticleStyle=[{Name:"任意",CSS:"Selected"},{Name:"童话",CSS:""},{Name:"科幻",CSS:""},{Name:"奇幻",CSS:""},{Name:"旅行",CSS:""},{Name:"动物",CSS:""},{Name:"家庭亲子",CSS:""},{Name:"校园生活",CSS:""},{Name:"科普",CSS:""},{Name:"节日文化",CSS:""},{Name:"成长",CSS:""},{Name:"人励志",CSS:""},{Name:"环保",CSS:""}];
21
   
21
   
22
     const hiddenhelp=wx.getStorageSync('HiddenWordInputHelp');
22
     const hiddenhelp=wx.getStorageSync('HiddenWordInputHelp');
23
 
23
 
24
     that.setData({
24
     that.setData({
25
       Containnerheight: main.getWindowHeight(),
25
       Containnerheight: main.getWindowHeight(),
26
       Grade:grade,
26
       Grade:grade,
27
-      ArticleCategory:articleCategory,
27
+      ArticleStyle:ArticleStyle,
28
       IsShowPanelHelp:!hiddenhelp,
28
       IsShowPanelHelp:!hiddenhelp,
29
       KeyboardBtnName:"next",
29
       KeyboardBtnName:"next",
30
     });
30
     });
@@ -32,6 +32,7 @@ Page({
32
   },
32
   },
33
   onShow:function(e){
33
   onShow:function(e){
34
     var that = this;
34
     var that = this;
35
+    app.globalData.SelectedWords=common.removeDuplicateAndTrimStrings(app.globalData.SelectedWords);
35
     that.data.Words=[];
36
     that.data.Words=[];
36
     for(let i=0;i<10;i++){
37
     for(let i=0;i<10;i++){
37
       let obj={};
38
       let obj={};
@@ -147,20 +148,20 @@ Page({
147
   selectBtn:function(e){
148
   selectBtn:function(e){
148
     const index=e.currentTarget.dataset.index;
149
     const index=e.currentTarget.dataset.index;
149
     const id=e.currentTarget.dataset.id;
150
     const id=e.currentTarget.dataset.id;
151
+    
150
     let arr=this.data.Grade;
152
     let arr=this.data.Grade;
151
     if (id==1)
153
     if (id==1)
152
-      arr=this.data.ArticleCategory;
154
+      arr=this.data.ArticleStyle;
153
     for(let i=0;i<arr.length;i++){
155
     for(let i=0;i<arr.length;i++){
156
+      arr[i].CSS="";
154
       if (i==index)
157
       if (i==index)
155
         arr[i].CSS="Selected";
158
         arr[i].CSS="Selected";
156
-      else
157
-        arr[i].CSS="";
158
     }
159
     }
159
     if (id==1){
160
     if (id==1){
160
       this.setData({
161
       this.setData({
161
-        ArticleCategory:arr,
162
+        ArticleStyle:arr,
162
       });
163
       });
163
-      wx.setStorageSync('ArticleCategory', arr);
164
+      wx.setStorageSync('ArticleStyle', arr);
164
     }
165
     }
165
     else{
166
     else{
166
       this.setData({
167
       this.setData({
@@ -177,13 +178,31 @@ Page({
177
   },
178
   },
178
   goto: function (e) {
179
   goto: function (e) {
179
     let that=this;
180
     let that=this;
181
+    var url=e.currentTarget.dataset.url;
182
+
180
     app.globalData.SelectedWords=[];
183
     app.globalData.SelectedWords=[];
181
     for(let i=0;i<that.data.Words.length;i++){
184
     for(let i=0;i<that.data.Words.length;i++){
182
       if (that.data.Words[i].Word)
185
       if (that.data.Words[i].Word)
183
         app.globalData.SelectedWords.push(that.data.Words[i].Word);
186
         app.globalData.SelectedWords.push(that.data.Words[i].Word);
184
     }
187
     }
185
-    //debugger;
186
-    var url=e.currentTarget.dataset.url;
188
+    app.globalData.SelectedWords=common.removeDuplicateAndTrimStrings(app.globalData.SelectedWords);
189
+    
190
+    if (url=="article"){
191
+      let arr=this.data.Grade;
192
+      for(let i=0;i<arr.length;i++){
193
+        if (arr[i].CSS=="Selected"){
194
+          url+="?Level="+i;
195
+          break;
196
+        }
197
+      }
198
+      arr=this.data.ArticleStyle;
199
+      for(let i=0;i<arr.length;i++){
200
+        if (arr[i].CSS=="Selected"){
201
+          url+="&ArticleStyle="+arr[i].Name;
202
+          break;
203
+        }
204
+      }
205
+    }
187
     wx.navigateTo({
206
     wx.navigateTo({
188
       url: url,
207
       url: url,
189
     });
208
     });

+ 2 - 2
pages/main/wordsinput.json

@@ -65,10 +65,10 @@
65
     <view class="panelMenu11 FlexColumn">
65
     <view class="panelMenu11 FlexColumn">
66
       <view class="text04 text06">短文主题</view>
66
       <view class="text04 text06">短文主题</view>
67
       <view class="panelMenu111 FlexRow">
67
       <view class="panelMenu111 FlexRow">
68
-        <view class="btn btn{{item.CSS}} FlexRow" wx:for="{{ArticleCategory}}" wx:key="index" capture-bind:tap="selectBtn" data-id="1" data-index="{{index}}">{{item.Name}}</view>
68
+        <view class="btn btn{{item.CSS}} FlexRow" wx:for="{{ArticleStyle}}" wx:key="index" capture-bind:tap="selectBtn" data-id="1" data-index="{{index}}">{{item.Name}}</view>
69
       </view>
69
       </view>
70
     </view>
70
     </view>
71
-    <view class="btn2 FlexRow">
71
+    <view class="btn2 FlexRow" catch:tap="goto" data-url="article">
72
       <image src="../images/sysIcon_b01.png" class="sysIcon_b01"></image>
72
       <image src="../images/sysIcon_b01.png" class="sysIcon_b01"></image>
73
       <view>生成短文</view>
73
       <view>生成短文</view>
74
     </view>
74
     </view>

+ 1 - 0
pages/main/wordsinput.wxss

@@ -32,6 +32,7 @@ function getData(url, callback) {
32
 }
32
 }
33
 
33
 
34
 function postData(url, postData, callback) {
34
 function postData(url, postData, callback) {
35
+  console.log("加密前的结果为===", url);
35
   var url = common.Encrypt(url);
36
   var url = common.Encrypt(url);
36
   //console.log("加密后的结果为===",url);
37
   //console.log("加密后的结果为===",url);
37
   wx.request({
38
   wx.request({

+ 16 - 1
utils/util.js

@@ -502,6 +502,20 @@ function filterWordsWithSpecialChars(words) {
502
   return words.filter(word => word && /^[a-zA-Z\s'’-]+$/.test(word));
502
   return words.filter(word => word && /^[a-zA-Z\s'’-]+$/.test(word));
503
 }
503
 }
504
 
504
 
505
+/**
506
+ * 字符串数组去重并去除每个字符串的前后空格
507
+ * @param {string[]} arr - 输入的字符串数组
508
+ * @returns {string[]} 去重并去除前后空格后的数组
509
+ */
510
+function removeDuplicateAndTrimStrings(arr) {
511
+  if (!Array.isArray(arr)) {
512
+      return [];
513
+  }
514
+  
515
+  // 先对每个字符串进行trim处理,然后使用Set去重
516
+  return [...new Set(arr.map(str => str ? str.trim() : ''))];
517
+}
518
+
505
 module.exports = {
519
 module.exports = {
506
   formatTime: formatTime,
520
   formatTime: formatTime,
507
   formatDateCHS: formatDateCHS,
521
   formatDateCHS: formatDateCHS,
@@ -527,5 +541,6 @@ module.exports = {
527
   formatDateENG: formatDateENG,
541
   formatDateENG: formatDateENG,
528
   formatMoney:formatMoney,
542
   formatMoney:formatMoney,
529
   initMonthCalendar:initMonthCalendar,
543
   initMonthCalendar:initMonthCalendar,
530
-  filterWordsWithSpecialChars:filterWordsWithSpecialChars
544
+  filterWordsWithSpecialChars:filterWordsWithSpecialChars,
545
+  removeDuplicateAndTrimStrings:removeDuplicateAndTrimStrings,
531
 }
546
 }